mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-09 17:19:26 +00:00
Compare commits
332 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf974ffcc2 | ||
|
|
a90513c71d | ||
|
|
27838bf4e0 | ||
|
|
9f113278ee | ||
|
|
5739d0ee4c | ||
|
|
ace4b331e7 | ||
|
|
ee01458bc4 | ||
|
|
16aebb0c5d | ||
|
|
43cea334c2 | ||
|
|
561ce0d559 | ||
|
|
5bccbff58b | ||
|
|
72a8aa325f | ||
|
|
2b0cc18899 | ||
|
|
2b818a5116 | ||
|
|
19e47c804f | ||
|
|
b537e36696 | ||
|
|
e7cef36819 | ||
|
|
a0973894e8 | ||
|
|
edf9f269d4 | ||
|
|
c17ebc09c4 | ||
|
|
7dfe5be985 | ||
|
|
4e086328ee | ||
|
|
aa18675760 | ||
|
|
4bbb62d6fa | ||
|
|
5a0fad4901 | ||
|
|
3a8d8ab2d1 | ||
|
|
83ae005c70 | ||
|
|
81b16de62b | ||
|
|
2d3941a43e | ||
|
|
240feadc0c | ||
|
|
be59d1c9c2 | ||
|
|
01106c82e0 | ||
|
|
e94a86fcfb | ||
|
|
63d509d422 | ||
|
|
e56730ee25 | ||
|
|
0f2a339e0b | ||
|
|
70954f89b4 | ||
|
|
622db82af5 | ||
|
|
10576b064a | ||
|
|
7586303ee8 | ||
|
|
5e074a5cbd | ||
|
|
0b59876919 | ||
|
|
ced1ee94a4 | ||
|
|
b03a1f7ac2 | ||
|
|
47ee830867 | ||
|
|
4db59dc013 | ||
|
|
503988e3a7 | ||
|
|
dabf132d31 | ||
|
|
54b5b5a42f | ||
|
|
60ab87875c | ||
|
|
122a99a6fe | ||
|
|
b11da036d1 | ||
|
|
e04ee4dcc3 | ||
|
|
9ad48d30dc | ||
|
|
8803e6f495 | ||
|
|
df12e9fd79 | ||
|
|
ade6877a7d | ||
|
|
b38b43eef9 | ||
|
|
f9b912d365 | ||
|
|
6c97d86610 | ||
|
|
6299161980 | ||
|
|
31b514f8df | ||
|
|
853ae9d5fe | ||
|
|
5a02c43cc1 | ||
|
|
c2c0030f1b | ||
|
|
e048f5b822 | ||
|
|
9c3e0ed23b | ||
|
|
0e39c24f28 | ||
|
|
25871f4e48 | ||
|
|
014d92dc13 | ||
|
|
5e5f277e21 | ||
|
|
f3c14063c3 | ||
|
|
763ee1b4ed | ||
|
|
cd52174d82 | ||
|
|
bb3b09beb9 | ||
|
|
a6421bec2b | ||
|
|
642933b3d9 | ||
|
|
1100da1a1d | ||
|
|
5cc166254d | ||
|
|
b6f93dbc7d | ||
|
|
6a0782d962 | ||
|
|
f065776565 | ||
|
|
277dbb1b71 | ||
|
|
e05d60be7d | ||
|
|
b0f3fa1ffd | ||
|
|
6b48fec247 | ||
|
|
aa09f9cde3 | ||
|
|
bd30a120ae | ||
|
|
8b725c190b | ||
|
|
0aedc66ed0 | ||
|
|
81c8b88dc3 | ||
|
|
67d8d461bd | ||
|
|
5309211043 | ||
|
|
f274e1aaa0 | ||
|
|
9fd4034855 | ||
|
|
003b63990f | ||
|
|
2cd620b521 | ||
|
|
0841b70dc4 | ||
|
|
986ef9f085 | ||
|
|
d8ee4f1e32 | ||
|
|
3eb1de4055 | ||
|
|
0e4ae4d081 | ||
|
|
95a3305bd4 | ||
|
|
f7d196f36d | ||
|
|
9887fbbdac | ||
|
|
6aca81e534 | ||
|
|
51d5584829 | ||
|
|
2dc1a26f1c | ||
|
|
adfe5f7d14 | ||
|
|
b6b8320518 | ||
|
|
f270605936 | ||
|
|
d2bc99189b | ||
|
|
4774db37bd | ||
|
|
59f9907646 | ||
|
|
ffb0f8ac1d | ||
|
|
a0b305a7e4 | ||
|
|
65bcf4f4c6 | ||
|
|
6001cc3a41 | ||
|
|
0a874d31a9 | ||
|
|
6155304d7f | ||
|
|
ac78efff1b | ||
|
|
f212c8b6b7 | ||
|
|
930378058d | ||
|
|
2ac63b85b9 | ||
|
|
a9d64010e3 | ||
|
|
ab9f508ffc | ||
|
|
757738bf23 | ||
|
|
b56f970e0a | ||
|
|
e923ec451e | ||
|
|
d3fe58bcc7 | ||
|
|
7e002af3a9 | ||
|
|
b19432ee53 | ||
|
|
2d1293ff51 | ||
|
|
3d5ee41bb6 | ||
|
|
453537dc33 | ||
|
|
8711881d3c | ||
|
|
bf2f752116 | ||
|
|
95cd3e7c64 | ||
|
|
dd44025dde | ||
|
|
e8181b4d9b | ||
|
|
83b507e672 | ||
|
|
e16c31517e | ||
|
|
d6f56065d5 | ||
|
|
25371439df | ||
|
|
6b0ebd3e47 | ||
|
|
bca5a245a7 | ||
|
|
7592b12979 | ||
|
|
e0af5afd4f | ||
|
|
3753bcd43d | ||
|
|
0cd11e136b | ||
|
|
5b8076510a | ||
|
|
01e513c876 | ||
|
|
cbb28edde3 | ||
|
|
b7bcbf2f46 | ||
|
|
34dfe5604b | ||
|
|
ef2a482c45 | ||
|
|
1e49d3f05c | ||
|
|
eeeff45f70 | ||
|
|
6bcd4a3b10 | ||
|
|
3bb181fb7d | ||
|
|
5fb4c24fe4 | ||
|
|
ff1f499b9f | ||
|
|
6eca8c6c85 | ||
|
|
e31731cd37 | ||
|
|
d669d93d81 | ||
|
|
cb5a83096d | ||
|
|
468927a30f | ||
|
|
0a279b5dba | ||
|
|
167931fc01 | ||
|
|
81f3d9f3d2 | ||
|
|
37cb28e910 | ||
|
|
b56e34c3d2 | ||
|
|
33c3513184 | ||
|
|
a8f259fbad | ||
|
|
686e445c9b | ||
|
|
02ab868dc7 | ||
|
|
1a63f6e737 | ||
|
|
e5652fbf7f | ||
|
|
434aed98d0 | ||
|
|
59280239e9 | ||
|
|
6871741ee0 | ||
|
|
5fb797c201 | ||
|
|
1369aa777b | ||
|
|
13ccf7c9b0 | ||
|
|
1c5f4f3853 | ||
|
|
ef1ce11154 | ||
|
|
61c30822fb | ||
|
|
64328723c8 | ||
|
|
517872e072 | ||
|
|
4ea5b142f4 | ||
|
|
f6fd116274 | ||
|
|
dfec8d0cb2 | ||
|
|
90337d37f7 | ||
|
|
af3b3e2f71 | ||
|
|
10dd66d416 | ||
|
|
9bf3916909 | ||
|
|
ef1a9cd1f7 | ||
|
|
858434940a | ||
|
|
1a4f02f6df | ||
|
|
10dfa43696 | ||
|
|
90295d7c13 | ||
|
|
de0c56b466 | ||
|
|
e816b93c46 | ||
|
|
77a6a0fb87 | ||
|
|
09416e7fe1 | ||
|
|
ea74b06286 | ||
|
|
c767f40875 | ||
|
|
19b9ebe3fd | ||
|
|
8b593489e7 | ||
|
|
ee72dd5f3f | ||
|
|
4e26d65626 | ||
|
|
0ef8a15ed4 | ||
|
|
02e459d5f6 | ||
|
|
aa80cd9d6b | ||
|
|
6f004f1ffd | ||
|
|
1ad7bac9ce | ||
|
|
469f12c645 | ||
|
|
d3f4e65686 | ||
|
|
c5ba5ccd89 | ||
|
|
b35e0dd43c | ||
|
|
dc085fbe2a | ||
|
|
f1f0e50e08 | ||
|
|
d3cfd7b5d9 | ||
|
|
71fedff180 | ||
|
|
7c6ca98358 | ||
|
|
2f8e7f9029 | ||
|
|
af50093b9b | ||
|
|
f5c45c7ebb | ||
|
|
93ac084d4b | ||
|
|
8a934e93c8 | ||
|
|
84f0fa0ed4 | ||
|
|
76d91901cd | ||
|
|
c6b6a8a3a0 | ||
|
|
e359911d60 | ||
|
|
3cbf328fee | ||
|
|
512e7fe290 | ||
|
|
70f6613953 | ||
|
|
566d38c39a | ||
|
|
03162c06ee | ||
|
|
81869ec715 | ||
|
|
7130daf65d | ||
|
|
8f76929643 | ||
|
|
d930b3341d | ||
|
|
54c2a9923b | ||
|
|
24875bda88 | ||
|
|
54fd52a924 | ||
|
|
774d61782f | ||
|
|
f2ef1c3f3b | ||
|
|
f192c194df | ||
|
|
efded3790b | ||
|
|
4d4045674a | ||
|
|
111bead68d | ||
|
|
6e511c8368 | ||
|
|
43cdab9821 | ||
|
|
a1984fed70 | ||
|
|
01ae55f854 | ||
|
|
2ad4fa56ee | ||
|
|
f36273aba7 | ||
|
|
1b08f14add | ||
|
|
a1d30abdf2 | ||
|
|
65c1a6aef9 | ||
|
|
00f889778c | ||
|
|
13a2bc6368 | ||
|
|
15f8b3cca1 | ||
|
|
6abfc0ec46 | ||
|
|
c266a880c3 | ||
|
|
201820376d | ||
|
|
1dd73675e9 | ||
|
|
2329fd3c19 | ||
|
|
e040a1c711 | ||
|
|
fba6f66e1a | ||
|
|
1337980ec3 | ||
|
|
bff7f7b7c3 | ||
|
|
9b15c762c8 | ||
|
|
3691c5e343 | ||
|
|
815e1b0ef9 | ||
|
|
95c37166e7 | ||
|
|
b0a839222b | ||
|
|
aa0a9ff7ee | ||
|
|
a6f841c380 | ||
|
|
0638660e31 | ||
|
|
bc2779f1c1 | ||
|
|
aafc61457f | ||
|
|
6e0aee6c01 | ||
|
|
4dc64331f6 | ||
|
|
ae8ce290c1 | ||
|
|
0f60d24921 | ||
|
|
f5c54341ac | ||
|
|
9e8dcba265 | ||
|
|
3a21e72f32 | ||
|
|
44f79b6bb9 | ||
|
|
f40f1d8183 | ||
|
|
0ffe8c714c | ||
|
|
5f00c98583 | ||
|
|
b12e3d06a9 | ||
|
|
8f97858987 | ||
|
|
e229d85baa | ||
|
|
85a3a48cd2 | ||
|
|
79f39a35a6 | ||
|
|
a25f81483c | ||
|
|
1eb72d1621 | ||
|
|
91c558e43b | ||
|
|
207772f0e7 | ||
|
|
9b9bdb3af6 | ||
|
|
1924385156 | ||
|
|
20984b36b5 | ||
|
|
5a42d00a1f | ||
|
|
37569a3ae6 | ||
|
|
a0bd050330 | ||
|
|
5e3e0d4081 | ||
|
|
569881c1c1 | ||
|
|
e25209453a | ||
|
|
88b134c50f | ||
|
|
cd5aae1b16 | ||
|
|
ef705fccc7 | ||
|
|
72145109ab | ||
|
|
a7ceabdc33 | ||
|
|
8bd8950514 | ||
|
|
c2e2fe5c4b | ||
|
|
19437cd694 | ||
|
|
338677a0fb | ||
|
|
5462d69dd1 | ||
|
|
2158fc18da | ||
|
|
898ae8cbce | ||
|
|
82540bab5e | ||
|
|
ba2cec3c12 | ||
|
|
43b0245fa1 | ||
|
|
ed2759402a | ||
|
|
8b4178d416 | ||
|
|
4233ade781 | ||
|
|
35f3f3eec8 | ||
|
|
3577876cac |
480 changed files with 42650 additions and 8841 deletions
26
.github/git/git-help.md
vendored
26
.github/git/git-help.md
vendored
|
|
@ -44,6 +44,32 @@ To remove the effects of `git add .` and `git commit -m "test"` or just `git add
|
|||
git reset --soft HEAD~1
|
||||
```
|
||||
|
||||
To remove **all uncommitted and untracked changes** in Git and reset your working tree to the last commit:
|
||||
|
||||
```bash
|
||||
git reset --hard
|
||||
git clean -fd
|
||||
```
|
||||
|
||||
To modify the last pushed commit:
|
||||
|
||||
```bash
|
||||
# Undo the last commit but keep the changes in your working tree
|
||||
git reset --soft HEAD~1
|
||||
|
||||
# Make your additional modifications
|
||||
# edit files...
|
||||
|
||||
# Stage everything
|
||||
git add .
|
||||
|
||||
# Create a new commit
|
||||
git commit -m "Updated commit message"
|
||||
|
||||
# Force-push to replace the remote commit
|
||||
git push --force-with-lease
|
||||
```
|
||||
|
||||
---------------
|
||||
|
||||
## Releasing instructions
|
||||
|
|
|
|||
47
.github/workflows/vs2022.yml
vendored
47
.github/workflows/vs2022.yml
vendored
|
|
@ -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
99
.github/workflows/vs2026.yml
vendored
Normal 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 }}
|
||||
12
.gitmodules
vendored
12
.gitmodules
vendored
|
|
@ -1,9 +1,3 @@
|
|||
[submodule "hyperdbg/dependencies/zydis"]
|
||||
path = hyperdbg/dependencies/zydis
|
||||
url = https://github.com/HyperDbg/zydis.git
|
||||
[submodule "hyperdbg/dependencies/pdbex"]
|
||||
path = hyperdbg/dependencies/pdbex
|
||||
url = https://github.com/HyperDbg/pdbex.git
|
||||
[submodule "hyperdbg/tests/script-engine-test"]
|
||||
path = hyperdbg/tests/script-engine-test
|
||||
url = https://github.com/HyperDbg/script-engine-test.git
|
||||
|
|
@ -13,3 +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
|
||||
|
|
|
|||
134
CHANGELOG.md
134
CHANGELOG.md
|
|
@ -4,6 +4,138 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.21.0.0] - 2026-07-05
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added structure for the hyperperf (Hardware Performance Counter) project ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- The 'unload' command checks whether any module is loaded or not ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
|
||||
- Exported SDK API for checking whether any module is loaded or not ([link](https://github.com/HyperDbg/HyperDbg/commit/19e47c804f50f5dbb698f314e66b7d685a87ac1f))
|
||||
- Added user mode and kernel mode PT parameter parser ([link](https://github.com/HyperDbg/HyperDbg/pull/631))
|
||||
- Added thread (TID) and process (PID) helper functions for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/pull/633))
|
||||
|
||||
### Changed
|
||||
- Separated SDK libraries for user mode and kernel mode modules ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
|
||||
- Fix pool manager uninitialize list corruption ([link](https://github.com/HyperDbg/HyperDbg/pull/629))
|
||||
- Fix 'access denied' error on loading all modules using 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))([link](https://github.com/HyperDbg/HyperDbg/commit/2b818a5116d80d466aab7b343d4aa9d1d640f082))
|
||||
- Fix the concatenation error for the "hyperkd" string on the hypertrace project (https://github.com/HyperDbg/HyperDbg/commit/2b0cc18899ff532d9d590a71bf880fee5456c15f))
|
||||
- Organized header files for the libhyperdbg project ([link](https://github.com/HyperDbg/HyperDbg/pull/632))
|
||||
|
||||
## [0.20.0.0-beta] - 2026-06-21
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Added the libipt library to the project and the SDK
|
||||
- Added Intel Processor Trace (PT) example app
|
||||
- Added Linux distinction and pragmas together with new platform functions ([link](https://github.com/HyperDbg/HyperDbg/commit/9c3e0ed23b5f4bb64bd305e546dd0e86ee1910d9))
|
||||
- Added interfaces to Linux port for the serial devices ([link](https://github.com/HyperDbg/HyperDbg/commit/31b514f8df40d81d44ae07a2328c02360ce488c3))
|
||||
- Added platform IOCTL interface ([link](https://github.com/HyperDbg/HyperDbg/pull/619))
|
||||
- Added typecast for wchar, mismatch on Linux and Windows ([link](https://github.com/HyperDbg/HyperDbg/commit/10576b064a9824ab655e7bea0e35e9556ee68ca4))
|
||||
- Added missing IOCTLs for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/commit/df12e9fd79851c8f378ec82a45066da510da507a))
|
||||
- Added NuGet packages for Windows SDK and WDK
|
||||
- Added Signal handler platform API for Linux ([link](https://github.com/HyperDbg/HyperDbg/pull/627))
|
||||
- Added contribution guidelines for Linux ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/linux#readme))
|
||||
|
||||
### Changed
|
||||
- Moved to Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/pull/626))
|
||||
- Zydis and pdbex submodules are updated to VS2026
|
||||
- Fix the new form of loading and unloading in the example app and PT app ([link](https://github.com/HyperDbg/HyperDbg/commit/9ad48d30dcf6b409ae86b2d08262584cd06f606e))
|
||||
- Check whether the top-level hypervisor is Hyper-V and disable/enable VPIDs based on that, thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/625))
|
||||
- Fix PT operation IOCTL buffer size ([link](https://github.com/HyperDbg/HyperDbg/commit/dabf132d31503843f90949f35f8dce4601d43126))
|
||||
- CI/CD updated with NuGet packages for Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/commit/5a0fad490124268550f955f594d1211d5c74f03d))
|
||||
|
||||
## [0.19.0.0-beta] - 2026-06-10
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- First release of the HyperTrace module ([link](https://url.hyperdbg.org/hypertrace))
|
||||
- HyperTrace now enables/disables VM-entry/VM-exit controls for Load and Save IA32_DEBUGCTL MSR
|
||||
- Added Legacy LBR support to the HyperTrace module
|
||||
- Added Architectural LBR support to the HyperTrace module
|
||||
- Added the '!lbr' command for performing different Last Branch Record (LBR) operations ([link](https://docs.hyperdbg.org/commands/extension-commands/lbr))
|
||||
- Added the '!lbrdump' command for dumping saved Last Branch Record (LBR) entries ([link](https://docs.hyperdbg.org/commands/extension-commands/lbrdump))
|
||||
- Added **lbr_save()** and **lbr_print()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print))
|
||||
- Added mock application for compiling SDK for Linux
|
||||
- Added '!help' alias for the '.help' command
|
||||
- Added 'vm' alias for the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Added **lbr_check()** and **lbr_restore()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore))
|
||||
- Added **lbr_restore_by_filter(filter)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter))
|
||||
- Added the 'kd' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Added the 'trace' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- Exported SDK API for detecting CPU vendors
|
||||
- Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589))
|
||||
- Exported SDK APIs for loading and unloading the 'kd' and the 'trace' modules
|
||||
- Exported SDK APIs for starting (installing) the 'kd' driver
|
||||
- Exported SDK APIs for loading/unloading all modules
|
||||
- Added tests for checking PE parser in 'hyperdbg-test' project
|
||||
- Added example for loading HyperDbg in VMI mode directly from libhyperdbg
|
||||
- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601))
|
||||
- Added transparent-mode evade mask selection thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/602))
|
||||
- Added synthetic MSR handling thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/605))
|
||||
- Added use of relative RSDS fixture paths when loading PDB symbols, thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/607))
|
||||
|
||||
### Changed
|
||||
- Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters))
|
||||
- Refactoring the IOCTL parameter checks and status routines
|
||||
- All basic types are now defined for Linux
|
||||
- VMX instructions are ported to platform-independent files to support Linux
|
||||
- All CPU-related intrinsic instructions are ported to platform-independent files to support Linux
|
||||
- HyperDbg SDK now compiles on Linux (GCC) for both user-mode and kernel-mode
|
||||
- Fix the 'wrmsr' command IOCTL checks by receiving output in the buffer ([link](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr))
|
||||
- Extensive refactoring of code base (doxygen, variables, function names)
|
||||
- Building certain modules on Linux and fixing CMake files thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/592))
|
||||
- Fix the '!hide' command's HyperEvade activation guard thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/593))
|
||||
- Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595))
|
||||
- PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe))
|
||||
- Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596))
|
||||
- The pool manager moved from 'hyperhv' to 'hyperkd'
|
||||
- The 'load' command could load all modules using a new alias 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
|
||||
- The 'unload' command could remove all modules using two new aliases 'unload all' and 'unload remove all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
|
||||
- Change device handle checks with module loading status checks for IOCTLs ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
|
||||
- Fix standard callbacks for the VMM module ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
|
||||
- Fix race condition bug within the pool manager
|
||||
|
||||
## [0.18.1.0] - 2026-04-09
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- HyperTrace now works with HyperDbg VMM ([link](https://github.com/HyperDbg/HyperDbg/pull/568))
|
||||
- Progress on implementing Last Branch Recode (LBR) ([link](https://github.com/HyperDbg/HyperDbg/commit/1dd73675e9cd78737e013ffb35bc712f385f387e))
|
||||
- Applying LBR registers on the VMCS instead of the DEBUGCTL MSR ([link](https://github.com/HyperDbg/HyperDbg/commit/15f8b3cca15448acd18d7e198740464a19ce4fe2))
|
||||
|
||||
### Changed
|
||||
- Fix the problem of the '!epthook' not finding the PML1 entry ([link](https://docs.hyperdbg.org/commands/extension-commands/epthook))
|
||||
- Fix the problem of getting the PML1 entry of the target address on Intel Core Ultra processors (#567) ([link](https://github.com/HyperDbg/HyperDbg/issues/567))
|
||||
- Fix the '.clang-format' formatting error
|
||||
- Restructure of the HyperTrace project
|
||||
- Add starting structure for supporting Intel Processor Trace (PT)
|
||||
|
||||
## [0.18.0.0] - 2026-02-16
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
### Added
|
||||
- Script engine now supports writing libraries using the '#include' keyword thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion))([link](https://github.com/HyperDbg/HyperDbg/issues/557))([link](https://github.com/HyperDbg/HyperDbg/pull/561))
|
||||
- Initial codes for the HyperTrace project by using Intel Last Branch Record (LBR) and Branch Trace Store (BTS) thanks to [@harimishal1](https://github.com/harimishal1) ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/hypertrace))
|
||||
- The HyperTrace project is now linked to the hyperkd
|
||||
- Initial efforts to port HyperDbg to Linux have started thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/563))
|
||||
|
||||
### Changed
|
||||
- Fix compilation error in Zydis with the new Windows WDK ([link](https://github.com/HyperDbg/zydis/commit/e61f59332ce49f8853006573ca853e404fafdd08))
|
||||
|
||||
## [0.17.0.0] - 2025-11-10
|
||||
New release of the HyperDbg Debugger. All credit for this release goes to [@xmaple555](https://github.com/xmaple555).
|
||||
|
||||
### Added
|
||||
- Added 1D and 2D arrays (multidimensional arrays) in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multidimensional-array))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
- Added compound assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#compound-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
- Added multiple assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multiple-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
|
||||
|
||||
### Changed
|
||||
- Fix bugs for interpreting 'db_pa, 'dd_pa', 'eb_pa', and 'ed_pa' keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))([link](https://github.com/HyperDbg/HyperDbg/pull/507))
|
||||
- Fix variable types in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/43b0245fa11b5c73ce4cd21d8b8787b86a05f89d))
|
||||
- Fix and update array index for boolean expressions in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/ba2cec3c12c3ff45ddc0004051884983ff62a0b3))
|
||||
|
||||
## [0.16.0.0] - 2025-09-08
|
||||
New release of the HyperDbg Debugger.
|
||||
|
||||
|
|
@ -46,7 +178,7 @@ New release of the HyperDbg Debugger.
|
|||
- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
|
||||
- Updated ia32-doc to fix VMCS PL3 SSP fields ([link](https://github.com/HyperDbg/ia32-doc))
|
||||
- Fix the terminating process issue of the '!syscall/!sysret' commands on 11 generation (Rocket Lake/Tiger Lake) and newer Intel processors ([link](https://github.com/HyperDbg/HyperDbg/issues/392))
|
||||
- Reenable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- Re-enable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
|
||||
- The '!mode' event command is now compatible with different EPT hook commands (e.g., !epthook, !epthook2, !monitor, .start, and .restart) ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
|
||||
- The '!mode' command doesn't need allocating extra EPTPs ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
|
||||
|
||||
|
|
|
|||
|
|
@ -8,49 +8,13 @@ HyperDbg is a large-scale project that requires a lot of time and effort from th
|
|||
|
||||
Please make sure to create a [discussion](https://github.com/orgs/HyperDbg/discussions) or an [issue](https://github.com/HyperDbg/HyperDbg/issues), or even better, join the HyperDbg groups ([Telegram](https://t.me/HyperDbg), [Discord](https://discord.gg/anSPsGUtzN), [Matrix](https://matrix.to/#/#hyperdbg-discussion:matrix.org)) on social media. Discuss the way you want to implement your changes and inform developers, because we often see people simultaneously working on the same issue. To avoid this collision, make sure to inform us before you start developing.
|
||||
|
||||
### Working on an Idea or a Task
|
||||
- We have a [wide range of ideas and tasks](https://github.com/orgs/HyperDbg/projects/2) that you might be interested in working on. You can choose a task and start working on it, and if you have any questions or need clarification, feel free to ask. This list will be updated frequently.
|
||||
|
||||
### Other Things to Work on
|
||||
- Writing blog posts and creating videos about use-cases of HyperDbg (make sure to add it to the [awesome](https://github.com/HyperDbg/awesome) repository).
|
||||
- Fixing unresolved GitHub [issues](https://github.com/HyperDbg/HyperDbg/issues).
|
||||
- Troubleshooting problems with running on Hyper-V's nested virtualization.
|
||||
- Troubleshooting problems with running on VirtualBox's nested virtualization.
|
||||
- Supporting KDNET (sending data over the network).
|
||||
- Enhancing HyperDbg's [Transparent Mode](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/operation-modes#transparent-mode), especially for anti-hypervisor methods.
|
||||
- Enhancing and adding more features to the ['.pe'](https://docs.hyperdbg.org/commands/meta-commands/.pe) command.
|
||||
- Adding HyperDbg to the system startup using UEFI.
|
||||
- Adding routines to activate and use Last Branch Record (LBR) and Branch Trace Store (BTS).
|
||||
- Creating a QT-based GUI.
|
||||
- Creating a SoftICE-style GUI.
|
||||
- Supporting nested-virtualization on HyperDbg itself.
|
||||
- Protecting HyperDbg code and memory from modification using VT-x capabilities.
|
||||
- Adding support for the Intel Processor Trace (PT).
|
||||
- Creating a wrapper that automatically interprets the [HyperDbg SDK](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/include/SDK) to GO, RUST, C#, Python, etc.
|
||||
- Creating syntax highlighting for dslang for different IDEs (VSCode, VIM, etc.).
|
||||
- Building HyperDbg using LLVM clang.
|
||||
- Helping us start supporting HyperDbg on Linux (discussion needed).
|
||||
- Helping us start supporting HyperDbg on AMD processors (discussion needed).
|
||||
- Adding digital (FPGA) modules to the hwdbg hardware debugger.
|
||||
- Creating a [ret-sync](https://github.com/bootleg/ret-sync) module for HyperDbg.
|
||||
- Adding fuzzing capabilities to HyperDbg (maybe integrating [AFL++](https://github.com/AFLplusplus/AFLplusplus) into HyperDbg).
|
||||
- Working on live memory migration and adding support for kernel-mode time travel debugging.
|
||||
- Integrating the [z3 project](https://github.com/Z3Prover/z3) into HyperDbg and adding commands based on the z3 solver.
|
||||
- Adding the [Bochs emulator](https://github.com/bochs-emu/Bochs) to HyperDbg.
|
||||
- ~~Creating commands to inspect and read details of PCIe devices.~~ Added: [<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)]
|
||||
- Creating different examples of how to use the SDK (using different programming languages).
|
||||
- Debugging and fixing bugs related to HyperDbg's physical serial communication.
|
||||
- Reading symbol information from modules in memory (currently, HyperDbg opens a file which continues the debugger).
|
||||
- Adding APIC virtualization.
|
||||
- Reading the list of modules for the '[lm](https://docs.hyperdbg.org/commands/debugging-commands/lm)' command directly from kernel-mode.
|
||||
- Detecting and fixing anti-hypervisor methods described [here](https://github.com/Ahora57/MAJESTY-technologies).
|
||||
- Investigating why the symbols parser (DIA SDK) could not read symbols of the 'kernel32!*'.
|
||||
- ~~Fixing the problem with [XSETBV instruction freezing](https://github.com/HyperDbg/HyperDbg/issues/429).~~ [[Fixed](https://github.com/HyperDbg/HyperDbg/pull/491)]
|
||||
- Adding an event function that detects coverage.
|
||||
- Bypassing [al-khaser](https://github.com/LordNoteworthy/al-khaser).
|
||||
- Creating the 'alias' command that converts or registers scripts as a command, for example: "alias !list .script list.dbg" (discussion needed).
|
||||
- Adding support for [Hardware Performance Counters (HPC)](https://en.wikipedia.org/wiki/Hardware_performance_counter).
|
||||
|
||||
- Any other interesting tasks you might find!
|
||||
|
||||
This list will be updated frequently.
|
||||
- Any other interesting ideas you might find! (Let's have a discussion before working on them.)
|
||||
|
||||
## Fixing Bugs
|
||||
|
||||
|
|
|
|||
|
|
@ -26,4 +26,5 @@ Just so you know – the attributions listed on this credits page are acknowledg
|
|||
- Björn Ruytenberg ([@0Xiphorus](https://twitter.com/0Xiphorus))
|
||||
- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3)) for his works on enhancing HyperEvade project
|
||||
- Artem Shishkin ([@honorary_bot](https://twitter.com/honorary_bot)) for always answering our hypervisor questions
|
||||
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
|
||||
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
|
||||
- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)
|
||||
58
README.md
58
README.md
|
|
@ -9,7 +9,7 @@
|
|||
# HyperDbg Debugger
|
||||
|
||||
<a href="https://hyperdbg.org/"><img align="right" width="150" height="150" src="https://github.com/HyperDbg/graphics/raw/master/Art%20Board/HyperDbg-Cat.Circle.Compressed.png" alt="HyperDbg Debugger"></a></br>
|
||||
**HyperDbg Debugger** is a free (as in free beer and freedom), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
|
||||
**HyperDbg Debugger** is a free (as in free beer), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
|
||||
|
||||
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **[Mastodon](https://infosec.exchange/@hyperdbg)** to get notified about new releases, or join any of the HyperDbg groups, where you can ask developers and open-source reversing enthusiasts for help setting up and using HyperDbg.
|
||||
|
||||
|
|
@ -73,19 +73,7 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
|
|||
|
||||
<summary><b>Other paper built upon HyperDbg...</b></summary>
|
||||
|
||||
|
||||
**2. [The Reversing Machine: Reconstructing Memory Assumptions](https://arxiv.org/pdf/2405.00298)** [[arXiv](https://arxiv.org/abs/2405.00298)]
|
||||
|
||||
```
|
||||
@article{karvandi2024reversing,
|
||||
title={The Reversing Machine: Reconstructing Memory Assumptions},
|
||||
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and van der Kouwe, Erik},
|
||||
journal={arXiv preprint arXiv:2405.00298},
|
||||
year={2024}
|
||||
}
|
||||
```
|
||||
|
||||
**3. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
|
||||
**2. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
|
||||
|
||||
```
|
||||
@inproceedings{karvandi2025hwdbg,
|
||||
|
|
@ -97,6 +85,45 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
|
|||
}
|
||||
```
|
||||
|
||||
**3. [HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg (DEBT'25)](https://www.jot.fm/contents/issue_2026_01/a8.html)** [[PDF](https://www.jot.fm/issues/issue_2026_01/a8.pdf)]
|
||||
|
||||
```
|
||||
@article{ruytenberg2026hyperevade,
|
||||
title={HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg},
|
||||
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina},
|
||||
journal={Journal of Object Technology},
|
||||
volume={25},
|
||||
number={1},
|
||||
pages={1--3},
|
||||
year={2026},
|
||||
publisher={Association Internationale pour les Technologies Objets}
|
||||
}
|
||||
```
|
||||
|
||||
**4. [Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher (EuroSys'26)](https://dl.acm.org/doi/abs/10.1145/3767295.3803583)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3767295.3803583)]
|
||||
|
||||
```
|
||||
@inproceedings{ruytenberg2026digital,
|
||||
title={Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher},
|
||||
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina and Bos, Herbert and van der Kouwe, Erik and Slowinska, Asia},
|
||||
booktitle={Proceedings of the 21st European Conference on Computer Systems},
|
||||
pages={484--496},
|
||||
year={2026}
|
||||
}
|
||||
```
|
||||
|
||||
**5. [TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction (AsiaCCS'26)](https://dl.acm.org/doi/10.1145/3779208.3785293)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3779208.3785293)]
|
||||
|
||||
```
|
||||
@inproceedings{karvandi2026trm,
|
||||
title={TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction},
|
||||
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and Slowinska, Asia and van der Kouwe, Erik},
|
||||
booktitle={Proceedings of the ACM Asia Conference on Computer and Communications Security},
|
||||
pages={68--82},
|
||||
year={2026}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
You can also read [this article](https://research.hyperdbg.org/debugger/kernel-debugger-design/) as it describes the overall architecture, technical difficulties, design decisions, and internals of HyperDbg Debugger, [this article](https://research.hyperdbg.org/vmm/transparency/) about our efforts on vm-exit transparency, [this article](https://research.hyperdbg.org/debugger/chasing-bugs/) about chasing bugs within hypervisors, and [this article](https://research.hyperdbg.org/debugger/gaining-insights/) about new reverse engineering techniques introduced in HyperDbg. More articles, posts, and resources are available at the **[awesome](https://github.com/HyperDbg/awesome)** repo, and in addition, the **[slides](https://github.com/HyperDbg/slides)** repo provides presentation slides for further reference.
|
||||
|
|
@ -150,6 +177,9 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
|
|||
* Triggering and Counting System Management Mode (SMM) Interrupts (SMIs) [<a href="https://docs.hyperdbg.org/commands/extension-commands/smi" target="_blank">link</a>]
|
||||
* Attaching to the User-mode Process and Preventing Execution [<a href="https://docs.hyperdbg.org/commands/meta-commands/.attach" target="_blank">link</a>]
|
||||
* Intercepting Execution of XSETBV Instructions [<a href="https://docs.hyperdbg.org/commands/extension-commands/xsetbv" target="_blank">link</a>]
|
||||
* Writing Library Script Files [<a href="https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion" target="_blank">link</a>]
|
||||
* Enhanced Portable Executable (PE) Parser [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pe" target="_blank">link</a>]
|
||||
* Tracing Branches using Last Branch Record (LBR) [<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>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter" target="_blank">link</a>]
|
||||
|
||||
## How does it work?
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ DriverEntry(
|
|||
//
|
||||
DbgPrint("HyperDbg's device and major functions are loaded");
|
||||
|
||||
|
||||
ASSERT(NT_SUCCESS(Ntstatus));
|
||||
return Ntstatus;
|
||||
}
|
||||
|
|
@ -105,7 +106,7 @@ DrvUnload(PDRIVER_OBJECT DriverObject)
|
|||
//
|
||||
// Unloading VMM and Debugger
|
||||
//
|
||||
LoaderUninitializeLogTracer();
|
||||
LoaderUninitLogTracer();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ DrvDispatchIoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
//
|
||||
// DO NOT CHANGE CALLING OF THE FOLLOWING FUNCTION
|
||||
//
|
||||
PoolManagerCheckAndPerformAllocationAndDeallocation();
|
||||
// PoolManagerCheckAndPerformAllocationAndDeallocation();
|
||||
|
||||
if (g_AllowIOCTLFromUsermode)
|
||||
if (g_VmmInitialized)
|
||||
{
|
||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
//
|
||||
// Allow to server IOCTL
|
||||
//
|
||||
g_AllowIOCTLFromUsermode = TRUE;
|
||||
g_VmmInitialized = TRUE;
|
||||
|
||||
//
|
||||
// Fill the callbacks for the message tracer
|
||||
|
|
@ -90,7 +90,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
//
|
||||
// Not loaded
|
||||
//
|
||||
g_AllowIOCTLFromUsermode = FALSE;
|
||||
g_VmmInitialized = FALSE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ LoaderInitVmmAndReversingMachine()
|
|||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
LoaderUninitializeLogTracer()
|
||||
LoaderUninitLogTracer()
|
||||
{
|
||||
LogDebugInfo("Unloading HyperDbg's debugger...\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
//////////////////////////////////////////////////
|
||||
|
||||
VOID
|
||||
LoaderUninitializeLogTracer();
|
||||
LoaderUninitLogTracer();
|
||||
|
||||
BOOLEAN
|
||||
LoaderInitVmmAndReversingMachine();
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
BOOLEAN g_HandleInUse;
|
||||
|
||||
/**
|
||||
* @brief Determines whether the clients are allowed to send IOCTL to the drive or not
|
||||
* @brief Shows whether the VMM is initialized or not
|
||||
*
|
||||
*/
|
||||
BOOLEAN g_AllowIOCTLFromUsermode;
|
||||
BOOLEAN g_VmmInitialized;
|
||||
|
|
@ -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>
|
||||
|
|
@ -56,4 +56,7 @@
|
|||
<Filter>code\driver</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
examples/kernel/hyperdbg_driver/packages.config
Normal file
6
examples/kernel/hyperdbg_driver/packages.config
Normal 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>
|
||||
|
|
@ -1,135 +1,58 @@
|
|||
/**
|
||||
* @file hyperdbg-app.cpp
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Controller of the reversing machine's module
|
||||
* @details
|
||||
*
|
||||
* @version 0.2
|
||||
* @date 2023-02-01
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
PVOID g_SharedMessageBuffer = NULL;
|
||||
|
||||
/**
|
||||
* @brief Show messages
|
||||
*
|
||||
* @param Text
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hyperdbg_show_messages(const char * Text)
|
||||
static int
|
||||
ShowMessages(const char * Text)
|
||||
{
|
||||
printf("%s", Text);
|
||||
return 0;
|
||||
printf("%s", Text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Show messages (shared buffer)
|
||||
*
|
||||
* @param Text
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hyperdbg_show_messages_shared_buffer()
|
||||
static int
|
||||
LoadVmm()
|
||||
{
|
||||
printf("%s", (char *)g_SharedMessageBuffer);
|
||||
return 0;
|
||||
}
|
||||
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
|
||||
|
||||
/**
|
||||
* @brief Load the driver
|
||||
*
|
||||
* @return int return zero if it was successful or non-zero if there
|
||||
* was error
|
||||
*/
|
||||
int
|
||||
hyperdbg_load()
|
||||
{
|
||||
char CpuId[13] = {0};
|
||||
|
||||
//
|
||||
// Read the vendor string
|
||||
//
|
||||
hyperdbg_u_read_vendor_string(CpuId);
|
||||
|
||||
printf("current processor vendor is : %s\n", CpuId);
|
||||
|
||||
if (strcmp(CpuId, "GenuineIntel") == 0)
|
||||
if (!hyperdbg_u_detect_vmx_support())
|
||||
{
|
||||
printf("virtualization technology is vt-x\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("this program is not designed to run in a non-VT-x "
|
||||
"environment !\n");
|
||||
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Detect if the processor supports vmx operation
|
||||
//
|
||||
if (hyperdbg_u_detect_vmx_support())
|
||||
printf("[*] loading HyperDbg VMM...\n");
|
||||
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
|
||||
{
|
||||
printf("vmx operation is supported by your processor\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef ENV_WINDOWS
|
||||
printf("vmx operation is not supported by your processor "
|
||||
"(if you are using an Intel processor, it might be because VBS is not disabled!)\n");
|
||||
#endif
|
||||
printf("[-] cannot load the HyperDbg VMM\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
//
|
||||
// Set callback function for showing messages
|
||||
//
|
||||
hyperdbg_u_set_text_message_callback(hyperdbg_show_messages);
|
||||
|
||||
//
|
||||
// Test intepreter with shared buffer
|
||||
//
|
||||
// g_SharedMessageBuffer = hyperdbg_u_set_text_message_callback_using_shared_buffer(hyperdbg_show_messages_shared_buffer);
|
||||
|
||||
//
|
||||
// Test interpreter
|
||||
//
|
||||
hyperdbg_u_connect_remote_debugger_using_named_pipe("\\\\.\\pipe\\HyperDbgPipe", TRUE);
|
||||
Sleep(10000);
|
||||
hyperdbg_u_run_command((CHAR *)"r");
|
||||
hyperdbg_u_run_command((CHAR *)".start path c:\\Windows\\system32\\calc.exe");
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
hyperdbg_u_continue_debuggee();
|
||||
printf("[+] HyperDbg VMM is running\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief main function
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
main()
|
||||
main(int argc, char ** argv)
|
||||
{
|
||||
if (hyperdbg_load() == 0)
|
||||
return main2(argc, argv);
|
||||
|
||||
if (LoadVmm() != 0)
|
||||
{
|
||||
//
|
||||
// HyperDbg driver loaded successfully
|
||||
//
|
||||
// hyperdbg_unload();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("err, in loading HyperDbg\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
hyperdbg_u_run_command((CHAR*)"lm");
|
||||
|
||||
printf("[*] unloading HyperDbg VMM...\n");
|
||||
|
||||
//
|
||||
// Unload the driver
|
||||
//
|
||||
hyperdbg_u_unload_vmm();
|
||||
hyperdbg_u_unload_kd();
|
||||
hyperdbg_u_stop_kd_driver();
|
||||
hyperdbg_u_uninstall_kd_driver();
|
||||
|
||||
printf("[+] done\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
583
examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
Normal file
583
examples/user/hyperdbg_app/code/hyperdbg-ipt.cpp
Normal 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;
|
||||
}
|
||||
16
examples/user/hyperdbg_app/header/example-ipt.h
Normal file
16
examples/user/hyperdbg_app/header/example-ipt.h
Normal 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);
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
//
|
||||
// Environment headers
|
||||
//
|
||||
#include "platform/user/header/Environment.h"
|
||||
#include "platform/general/header/Environment.h"
|
||||
|
||||
//
|
||||
// Windows SDK headers
|
||||
|
|
@ -38,3 +38,8 @@
|
|||
//
|
||||
#include "SDK/HyperDbgSdk.h"
|
||||
#include "SDK/imports/user/HyperDbgLibImports.h"
|
||||
|
||||
//
|
||||
// Other internal headers
|
||||
//
|
||||
#include "example-ipt.h"
|
||||
|
|
|
|||
|
|
@ -11,10 +11,11 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\..\platform\user\header\Environment.h" />
|
||||
<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">
|
||||
|
|
@ -29,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>
|
||||
|
|
@ -50,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>
|
||||
|
|
@ -84,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>
|
||||
|
|
@ -98,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">
|
||||
|
|
|
|||
|
|
@ -15,11 +15,14 @@
|
|||
<ClInclude Include="header\pch.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\platform\user\header\Environment.h">
|
||||
<Filter>header\platform</Filter>
|
||||
<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>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ MODELSIM = "/home/sina/intelFPGA/20.1/modelsim_ase/bin"
|
|||
# Check modelsim directory
|
||||
#
|
||||
if not os.path.exists(MODELSIM):
|
||||
print("[x] Error: The path mdoes not exist")
|
||||
print("[x] Error: The path does not exist")
|
||||
exit()
|
||||
else:
|
||||
print("[*] Oh, the modelsim path found :)")
|
||||
|
|
@ -152,6 +152,6 @@ print(result.stdout.decode())
|
|||
#
|
||||
# Run the generated WLF file
|
||||
#
|
||||
print("[*] openning file in vsim: " + latest_vcd_file + ".wlf")
|
||||
print("[*] opening file in vsim: " + latest_vcd_file + ".wlf")
|
||||
subprocess.run([MODELSIM_VSIM, latest_vcd_file + ".wlf",
|
||||
"-do", current_script_path + '/modelsim.tcl'])
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class DebuggerPacketInterpreter(
|
|||
val receivingData = Input(UInt(instanceInfo.bramDataWidth.W)) // data to be received in interpreter
|
||||
|
||||
//
|
||||
// Sending singals
|
||||
// Sending signals
|
||||
//
|
||||
val beginSendingBuffer = Output(Bool()) // should sender start sending buffers or not?
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class InterpreterInstanceInfo(
|
|||
val en = Input(Bool()) // chip enable signal
|
||||
|
||||
//
|
||||
// Sending singals
|
||||
// Sending signals
|
||||
//
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class InterpreterSendSuccessOrError(
|
|||
val lastSuccessOrError = Input(UInt(instanceInfo.bramDataWidth.W)) // input last error
|
||||
|
||||
//
|
||||
// Sending singals
|
||||
// Sending signals
|
||||
//
|
||||
val noNewDataSender = Output(Bool()) // should sender finish sending buffers or not?
|
||||
val dataValidOutput = Output(Bool()) // should sender send next buffer or not?
|
||||
|
|
|
|||
|
|
@ -351,7 +351,7 @@ class DebuggerPacketReceiver(
|
|||
|
||||
//
|
||||
// The receiving is done at this stage, either
|
||||
// was successful of unsucessful, we'll release the
|
||||
// was successful or unsuccessful, we'll release the
|
||||
// sharing bram resource by indicating that the receiving
|
||||
// module is no longer using the bram line
|
||||
//
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class SendReceiveSynchronizer(
|
|||
is(sIdle) {
|
||||
|
||||
//
|
||||
// Peform the resource sepration of shared BRAM
|
||||
// Perform the resource separation of shared BRAM
|
||||
// and apply priority to receive over send
|
||||
//
|
||||
when(io.plInSignal === true.B) {
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ class DebuggerPacketSender(
|
|||
wrData := HyperDbgSharedConstants.INDICATOR_OF_HYPERDBG_PACKET.U >> regTransferredIndicatorLength
|
||||
|
||||
//
|
||||
// Add to the length transfered
|
||||
// Add to the transferred length
|
||||
//
|
||||
regTransferredIndicatorLength := regTransferredIndicatorLength + instanceInfo.bramDataWidth.U
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,6 @@ object ScriptConstantTypes {
|
|||
|
||||
object ScriptEvalFunc {
|
||||
object ScriptOperators extends ChiselEnum {
|
||||
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncDereference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
|
||||
val sFuncUndefined, sFuncInc, sFuncDec, sFuncReference, sFuncOr, sFuncXor, sFuncAnd, sFuncAsr, sFuncAsl, sFuncAdd, sFuncSub, sFuncMul, sFuncDiv, sFuncMod, sFuncGt, sFuncLt, sFuncEgt, sFuncElt, sFuncEqual, sFuncNeq, sFuncJmp, sFuncJz, sFuncJnz, sFuncMov, sFuncStart_of_do_while, sFuncStart_of_do_while_commands, sFuncEnd_of_do_while, sFuncStart_of_for, sFuncFor_inc_dec, sFuncStart_of_for_ommands, sFuncEnd_of_if, sFuncIgnore_lvalue, sFuncPush, sFuncPop, sFuncCall, sFuncRet, sFuncPrint, sFuncFormats, sFuncEvent_enable, sFuncEvent_disable, sFuncEvent_clear, sFuncTest_statement, sFuncSpinlock_lock, sFuncSpinlock_unlock, sFuncEvent_sc, sFuncMicrosleep, sFuncPrintf, sFuncPause, sFuncFlush, sFuncEvent_trace_step, sFuncEvent_trace_step_in, sFuncEvent_trace_step_out, sFuncEvent_trace_instrumentation_step, sFuncEvent_trace_instrumentation_step_in, sFuncRdtsc, sFuncRdtscp, sFuncLbr_save, sFuncLbr_dump, sFuncLbr_print, sFuncLbr_restore, sFuncLbr_check, sFuncSpinlock_lock_custom_wait, sFuncEvent_inject, sFuncPoi, sFuncDb, sFuncDd, sFuncDw, sFuncDq, sFuncNeg, sFuncHi, sFuncLow, sFuncNot, sFuncCheck_address, sFuncDisassemble_len, sFuncDisassemble_len32, sFuncDisassemble_len64, sFuncInterlocked_increment, sFuncInterlocked_decrement, sFuncPhysical_to_virtual, sFuncVirtual_to_physical, sFuncPoi_pa, sFuncHi_pa, sFuncLow_pa, sFuncDb_pa, sFuncDd_pa, sFuncDw_pa, sFuncDq_pa, sFuncLbr_restore_by_filter, sFuncEd, sFuncEb, sFuncEq, sFuncInterlocked_exchange, sFuncInterlocked_exchange_add, sFuncEb_pa, sFuncEd_pa, sFuncEq_pa, sFuncInterlocked_compare_exchange, sFuncStrlen, sFuncStrcmp, sFuncMemcmp, sFuncStrncmp, sFuncWcslen, sFuncWcscmp, sFuncEvent_inject_error_code, sFuncMemcpy, sFuncMemcpy_pa, sFuncWcsncmp = Value
|
||||
}
|
||||
}
|
||||
|
|
@ -1,132 +1,3 @@
|
|||
Language: C
|
||||
BasedOnStyle: webkit
|
||||
AccessModifierOffset: -4
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: true
|
||||
AlignConsecutiveDeclarations: true
|
||||
|
||||
AlignConsecutiveMacros: true
|
||||
|
||||
AlignEscapedNewlines: Left
|
||||
AlignOperands: true
|
||||
|
||||
AlignTrailingComments: true
|
||||
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: TopLevel
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
|
||||
AlwaysBreakTemplateDeclarations: true #false
|
||||
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakStringLiterals: false
|
||||
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^begin_wpp|^end_wpp|^FUNC |^USESUFFIX |^USESUFFIX '
|
||||
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
|
||||
DerivePointerAlignment: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: AfterHash
|
||||
IndentWidth: 4
|
||||
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
|
||||
MacroBlockBegin: '^BEGIN_MODULE$|^BEGIN_TEST_CLASS$|^BEGIN_TEST_METHOD$'
|
||||
MacroBlockEnd: '^END_MODULE$|^END_TEST_CLASS$|^END_TEST_METHOD$'
|
||||
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None #All
|
||||
PointerAlignment: Middle
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
|
||||
Standard: Cpp11
|
||||
StatementMacros: [
|
||||
'EXTERN_C',
|
||||
'PAGED',
|
||||
'PAGEDX',
|
||||
'NONPAGED',
|
||||
'PNPCODE',
|
||||
'INITCODE',
|
||||
'_At_',
|
||||
'_When_',
|
||||
'_Success_',
|
||||
'_Check_return_',
|
||||
'_Must_inspect_result_',
|
||||
'_IRQL_requires_same_',
|
||||
'_IRQL_requires_',
|
||||
'_IRQL_requires_max_',
|
||||
'_IRQL_requires_min_',
|
||||
'_IRQL_saves_',
|
||||
'_IRQL_restores_',
|
||||
'_IRQL_saves_global_',
|
||||
'_IRQL_restores_global_',
|
||||
'_IRQL_raises_',
|
||||
'_IRQL_lowers_',
|
||||
'_Acquires_lock_',
|
||||
'_Releases_lock_',
|
||||
'_Acquires_exclusive_lock_',
|
||||
'_Releases_exclusive_lock_',
|
||||
'_Acquires_shared_lock_',
|
||||
'_Releases_shared_lock_',
|
||||
'_Requires_lock_held_',
|
||||
'_Use_decl_annotations_',
|
||||
'_Guarded_by_',
|
||||
'__drv_preferredFunction',
|
||||
'__drv_allocatesMem',
|
||||
'__drv_freesMem',
|
||||
]
|
||||
|
||||
TabWidth: '4'
|
||||
UseTab: Never
|
||||
|
||||
---
|
||||
|
||||
Language: Cpp
|
||||
BasedOnStyle: webkit
|
||||
AccessModifierOffset: -4
|
||||
|
|
@ -252,4 +123,4 @@ StatementMacros: [
|
|||
]
|
||||
|
||||
TabWidth: '4'
|
||||
UseTab: Never
|
||||
UseTab: Never
|
||||
|
|
@ -5,7 +5,11 @@ set(CMAKE_CXX_STANDARD 23)
|
|||
enable_language(ASM_MASM)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
if(LINUX)
|
||||
|
||||
message(STATUS "Building on Linux")
|
||||
elseif(WIN32)
|
||||
message(STATUS "Building on Windows")
|
||||
find_package(WDK REQUIRED)
|
||||
|
||||
include_directories(
|
||||
|
|
@ -48,22 +52,30 @@ target_link_libraries(hyperhv Zycore Zydis)
|
|||
add_subdirectory(hyperkd)
|
||||
target_link_libraries(hyperkd hyperlog hyperhv kdserial)
|
||||
|
||||
endif()
|
||||
|
||||
add_subdirectory(dependencies/pdbex/Source)
|
||||
#add_subdirectory(dependencies/pdbex/Source)
|
||||
|
||||
add_subdirectory(symbol-parser)
|
||||
target_link_libraries(symbol-parser pdbex)
|
||||
#add_subdirectory(symbol-parser)
|
||||
#target_link_libraries(symbol-parser pdbex)
|
||||
|
||||
#target_link_libraries(script-engine symbol-parser)
|
||||
|
||||
#add_subdirectory(hyperdbg-test)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
#add_subdirectory(symbol-parser)
|
||||
#target_link_libraries(symbol-parser pdbex)
|
||||
|
||||
#add_subdirectory(script-engine)
|
||||
#target_link_libraries(script-engine symbol-parser)
|
||||
|
||||
add_subdirectory(script-engine)
|
||||
target_link_libraries(script-engine symbol-parser)
|
||||
|
||||
link_directories(libraries/zydis/user libraries/keystone/release-lib)
|
||||
add_subdirectory(libhyperdbg)
|
||||
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone)
|
||||
|
||||
|
||||
add_subdirectory(hyperdbg-test)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(libhyperdbg Zycore Zydis script-engine keystone Threads::Threads)
|
||||
|
||||
add_subdirectory(hyperdbg-cli)
|
||||
target_link_libraries(hyperdbg-cli libhyperdbg)
|
||||
|
|
|
|||
3177
hyperdbg/dependencies/libipt/intel-pt.h
Normal file
3177
hyperdbg/dependencies/libipt/intel-pt.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1 +1 @@
|
|||
Subproject commit 42a9fbb821c7d140c5e00da60f5a5887c2fd8444
|
||||
Subproject commit 0e1144729a5b2d737cce11d1c0e083033630fff8
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit d45e7416b2123706c3695fa802e6b29543f1a549
|
||||
Subproject commit e910df2fa54273b1a489b39771d331036e8de2db
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# Code generated by Visual Studio kit, DO NOT EDIT.
|
||||
set(SourceFiles
|
||||
"hyperdbg-cli.cpp"
|
||||
"../include/platform/user/header/Environment.h"
|
||||
"../include/platform/general/header/Environment.h"
|
||||
)
|
||||
include_directories(
|
||||
"../include"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @file hyperdbg-cli.cpp
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Main HyperDbg Cli source coede
|
||||
* @brief Main HyperDbg Cli source code
|
||||
* @details
|
||||
* @version 0.1
|
||||
* @date 2020-04-11
|
||||
|
|
@ -10,16 +10,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// Environment headers
|
||||
//
|
||||
#include "platform/user/header/Environment.h"
|
||||
#ifdef _WIN32
|
||||
# include <Windows.h>
|
||||
# include <conio.h>
|
||||
#endif
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include "SDK/HyperDbgSdk.h"
|
||||
#include "SDK/imports/user/HyperDbgLibImports.h"
|
||||
|
|
@ -29,9 +28,9 @@ using namespace std;
|
|||
/**
|
||||
* @brief CLI main function
|
||||
*
|
||||
* @param argc
|
||||
* @param argv
|
||||
* @return int
|
||||
* @param argc the number of arguments
|
||||
* @param argv the arguments
|
||||
* @return int zero on success, 1 on failure
|
||||
*/
|
||||
int
|
||||
main(int argc, char * argv[])
|
||||
|
|
@ -43,12 +42,19 @@ main(int argc, char * argv[])
|
|||
//
|
||||
// Set console output code page to UTF-8
|
||||
//
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
printf("HyperDbg Debugger [version: %s, build: %s]\n", CompleteVersion, BuildVersion);
|
||||
printf("Please visit https://docs.hyperdbg.org for more information...\n");
|
||||
printf("HyperDbg is released under the GNU Public License v3 (GPLv3).\n\n");
|
||||
|
||||
#if BETA_VERSION == 1
|
||||
printf("Notice: This is a beta release and may contain bugs or stability issues. ");
|
||||
printf("If you encounter any problems, please report them and consider using the previous stable release.\n\n");
|
||||
#endif
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
//
|
||||
|
|
@ -79,7 +85,7 @@ main(int argc, char * argv[])
|
|||
//
|
||||
reset = TRUE;
|
||||
|
||||
GetMultiLinecCommand:
|
||||
GetMultiLineCommand:
|
||||
|
||||
string temp_command = "";
|
||||
|
||||
|
|
@ -120,7 +126,7 @@ main(int argc, char * argv[])
|
|||
//
|
||||
// Get next command
|
||||
//
|
||||
goto GetMultiLinecCommand;
|
||||
goto GetMultiLineCommand;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -143,9 +155,6 @@ copy "$(SolutionDir)miscellaneous\constants\pciid\pci.ids" "$(OutDir)constants\p
|
|||
<ItemGroup>
|
||||
<ClCompile Include="hyperdbg-cli.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\platform\user\header\Environment.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
|
|
|
|||
|
|
@ -17,9 +17,4 @@
|
|||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\platform\user\header\Environment.h">
|
||||
<Filter>header\platform</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -15,23 +15,23 @@ namespace fs = std::filesystem;
|
|||
|
||||
/**
|
||||
* @brief function to comment each line by adding ';' at the start
|
||||
* @param content
|
||||
* @param Content the content to comment out
|
||||
*
|
||||
* @return std::string
|
||||
*/
|
||||
std::string
|
||||
commentContent(const std::string & content)
|
||||
CommentContent(const std::string & Content)
|
||||
{
|
||||
std::istringstream iss(content);
|
||||
std::string line;
|
||||
std::string commentedContent;
|
||||
std::istringstream Iss(Content);
|
||||
std::string Line;
|
||||
std::string CommentedContent;
|
||||
|
||||
while (std::getline(iss, line))
|
||||
while (std::getline(Iss, Line))
|
||||
{
|
||||
commentedContent += line + "\n; ";
|
||||
CommentedContent += Line + "\n; ";
|
||||
}
|
||||
|
||||
return commentedContent;
|
||||
return CommentedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -42,9 +42,9 @@ commentContent(const std::string & content)
|
|||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
||||
ReadDirectoryAndCreateHwdbgTestCases(const CHAR * HwdbgScriptTestCasesPath)
|
||||
{
|
||||
CHAR tempFilePath[MAX_PATH] = {0};
|
||||
CHAR TempFilePath[MAX_PATH] = {0};
|
||||
|
||||
//
|
||||
// Iterate through the directory
|
||||
|
|
@ -61,7 +61,7 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
//
|
||||
// Get the file path
|
||||
//
|
||||
std::string filePath = entry.path().string();
|
||||
std::string FilePath = entry.path().string();
|
||||
|
||||
//
|
||||
// Output the file name
|
||||
|
|
@ -71,10 +71,10 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
//
|
||||
// Open the file and read its contents
|
||||
//
|
||||
std::ifstream file(filePath);
|
||||
if (file.is_open())
|
||||
std::ifstream File(FilePath);
|
||||
if (File.is_open())
|
||||
{
|
||||
std::string content((std::istreambuf_iterator<char>(file)),
|
||||
std::string Content((std::istreambuf_iterator<char>(File)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
//
|
||||
|
|
@ -84,19 +84,19 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
|
||||
// std::cout << content << std::endl;
|
||||
|
||||
std::string compiled_version_file_path = HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" + entry.path().filename().string() + ".hex.txt";
|
||||
std::string CompiledVersionFilePath = HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" + entry.path().filename().string() + ".hex.txt";
|
||||
|
||||
//
|
||||
// Run the test case command
|
||||
//
|
||||
printf("File content: %s\n", content.c_str());
|
||||
printf("File content: %s\n", Content.c_str());
|
||||
|
||||
if (!hwdbg_script_run_script(content.c_str(),
|
||||
if (!hwdbg_script_run_script(Content.c_str(),
|
||||
HWDBG_TEST_READ_INSTANCE_INFO_PATH,
|
||||
compiled_version_file_path.c_str(),
|
||||
CompiledVersionFilePath.c_str(),
|
||||
DEFAULT_INITIAL_BRAM_BUFFER_SIZE))
|
||||
{
|
||||
std::cout << "[-] Could not run the script: " << filePath << std::endl;
|
||||
std::cout << "[-] Could not run the script: " << FilePath << std::endl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
//
|
||||
// Parse the hwdbg compiled test cases from the file
|
||||
//
|
||||
if (!hyperdbg_u_setup_path_for_filename(compiled_version_file_path.c_str(), tempFilePath, MAX_PATH, FALSE))
|
||||
if (!hyperdbg_u_setup_path_for_filename(CompiledVersionFilePath.c_str(), TempFilePath, MAX_PATH, FALSE))
|
||||
{
|
||||
//
|
||||
// Error could not find the test case files
|
||||
|
|
@ -116,48 +116,48 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
std::ifstream compiledFile(tempFilePath);
|
||||
if (compiledFile.is_open())
|
||||
std::ifstream CompiledFile(TempFilePath);
|
||||
if (CompiledFile.is_open())
|
||||
{
|
||||
//
|
||||
// Read the existing content of the compiled file
|
||||
//
|
||||
std::string compiledContent((std::istreambuf_iterator<char>(compiledFile)),
|
||||
std::string CompiledContent((std::istreambuf_iterator<char>(CompiledFile)),
|
||||
std::istreambuf_iterator<char>());
|
||||
compiledFile.close(); // Close the file after reading
|
||||
CompiledFile.close(); // Close the file after reading
|
||||
|
||||
//
|
||||
// Comment the content
|
||||
//
|
||||
std::string commentedContent = commentContent(content);
|
||||
std::string CommentedContent = CommentContent(Content);
|
||||
|
||||
//
|
||||
// Concatenate the new content (prepend the original content)
|
||||
//
|
||||
std::string newContent = "; The raw script file is available at: " HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" +
|
||||
std::string NewContent = "; The raw script file is available at: " HWDBG_SCRIPT_TEST_CASE_COMPILED_SCRIPTS_DIRECTORY "\\" +
|
||||
entry.path().filename().string() +
|
||||
"\n;\n; !hw script " +
|
||||
commentedContent +
|
||||
CommentedContent +
|
||||
"\n" +
|
||||
compiledContent;
|
||||
CompiledContent;
|
||||
|
||||
//
|
||||
// Write the new content back to the file (overwriting it)
|
||||
//
|
||||
std::ofstream compiledFileOut(tempFilePath);
|
||||
if (compiledFileOut.is_open())
|
||||
std::ofstream CompiledFileOut(TempFilePath);
|
||||
if (CompiledFileOut.is_open())
|
||||
{
|
||||
compiledFileOut << newContent;
|
||||
compiledFileOut.close();
|
||||
CompiledFileOut << NewContent;
|
||||
CompiledFileOut.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not open file for writing: " << compiled_version_file_path << std::endl;
|
||||
std::cerr << "Could not open file for writing: " << CompiledVersionFilePath << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not open compiled file: " << compiled_version_file_path << std::endl;
|
||||
std::cerr << "Could not open compiled file: " << CompiledVersionFilePath << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "--------------------------------------------" << std::endl;
|
||||
|
|
@ -165,11 +165,11 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
//
|
||||
// Close the file
|
||||
//
|
||||
file.close();
|
||||
File.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not open file: " << filePath << std::endl;
|
||||
std::cerr << "Could not open file: " << FilePath << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -194,8 +194,8 @@ ReadDirectoryAndCreateHwdbgTestCases(const char * HwdbgScriptTestCasesPath)
|
|||
BOOLEAN
|
||||
HwdbgTestCreateTestCases()
|
||||
{
|
||||
int testNum = 0;
|
||||
CHAR dirPath[MAX_PATH] = {0};
|
||||
INT32 TestNum = 0;
|
||||
CHAR dirPath[MAX_PATH] = {0};
|
||||
|
||||
//
|
||||
// Parse the hwdbg test cases from the file
|
||||
|
|
|
|||
|
|
@ -43,10 +43,25 @@ main(int argc, char * argv[])
|
|||
printf("\n[x] The main command parser test cases failed\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_SCRIPT_SEMANTIC_TEST_CASES))
|
||||
else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_PE_PARSER))
|
||||
{
|
||||
//
|
||||
// # Test case 2
|
||||
// Testing PE parser helpers
|
||||
//
|
||||
if (TestPeParser())
|
||||
{
|
||||
printf("\n[*] The PE parser test cases passed successfully\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n[x] The PE parser test cases failed\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_SCRIPT_SEMANTIC_TEST_CASES))
|
||||
{
|
||||
//
|
||||
// # Test case 3
|
||||
// Testing script semantic test cases
|
||||
//
|
||||
if (TestSemanticScripts())
|
||||
|
|
@ -58,6 +73,21 @@ main(int argc, char * argv[])
|
|||
printf("\n[x] The script semantic test cases failed\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], TEST_CASE_PARAMETER_FOR_CODEVIEW_RSDS_PARSER))
|
||||
{
|
||||
//
|
||||
// # Test case 4
|
||||
// Testing CodeView RSDS parser helpers
|
||||
//
|
||||
if (TestCodeViewRsdsParser())
|
||||
{
|
||||
printf("\n[*] The CodeView RSDS parser test cases passed successfully\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n[x] The CodeView RSDS parser test cases failed\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(argv[1], TEST_HWDBG_FUNCTIONALITIES))
|
||||
{
|
||||
//
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Create a named pipe server
|
||||
* @brief Connect and transfer buffers via named pipe
|
||||
*
|
||||
* @return UINT32
|
||||
*/
|
||||
|
|
@ -204,14 +204,14 @@ NamedPipeServerCreatePipe(LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 Input
|
|||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
NamedPipeServerWaitForClientConntection(HANDLE PipeHandle)
|
||||
NamedPipeServerWaitForClientConnection(HANDLE PipeHandle)
|
||||
{
|
||||
//
|
||||
// Wait for the client to connect
|
||||
//
|
||||
BOOL bClientConnected = ConnectNamedPipe(PipeHandle, NULL);
|
||||
BOOLEAN ClientConnected = ConnectNamedPipe(PipeHandle, NULL);
|
||||
|
||||
if (FALSE == bClientConnected)
|
||||
if (FALSE == ClientConnected)
|
||||
{
|
||||
printf("err, occurred while connecting to the client (%x)\n",
|
||||
GetLastError());
|
||||
|
|
@ -234,9 +234,9 @@ NamedPipeServerWaitForClientConntection(HANDLE PipeHandle)
|
|||
* @return UINT32
|
||||
*/
|
||||
UINT32
|
||||
NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength)
|
||||
NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT32 MaximumReadBufferLength)
|
||||
{
|
||||
DWORD cbBytes;
|
||||
DWORD BytesTransferred;
|
||||
|
||||
//
|
||||
// We are connected to the client.
|
||||
|
|
@ -248,13 +248,13 @@ NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int Max
|
|||
//
|
||||
// Read client message
|
||||
//
|
||||
BOOL bResult = ReadFile(PipeHandle, // handle to pipe
|
||||
BufferToSave, // buffer to receive data
|
||||
MaximumReadBufferLength, // size of buffer
|
||||
&cbBytes, // number of bytes read
|
||||
NULL); // not overlapped I/O
|
||||
BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
|
||||
BufferToSave, // buffer to receive data
|
||||
MaximumReadBufferLength, // size of buffer
|
||||
&BytesTransferred, // number of bytes read
|
||||
NULL); // not overlapped I/O
|
||||
|
||||
if ((!bResult) || (0 == cbBytes))
|
||||
if ((!Result) || (0 == BytesTransferred))
|
||||
{
|
||||
printf("err, occurred while reading from the client (%x)\n",
|
||||
GetLastError());
|
||||
|
|
@ -265,29 +265,37 @@ NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int Max
|
|||
//
|
||||
// Number of bytes that the client sends to us
|
||||
//
|
||||
return cbBytes;
|
||||
return BytesTransferred;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send a message to the client over named pipe
|
||||
*
|
||||
* @param PipeHandle Handle of the named pipe
|
||||
* @param BufferToSend Buffer containing the message to send
|
||||
* @param BufferSize Size of the buffer to send
|
||||
* @return BOOLEAN TRUE if successful, FALSE otherwise
|
||||
*/
|
||||
BOOLEAN
|
||||
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
|
||||
char * BufferToSend,
|
||||
int BufferSize)
|
||||
CHAR * BufferToSend,
|
||||
INT32 BufferSize)
|
||||
{
|
||||
DWORD cbBytes;
|
||||
DWORD BytesTransferred;
|
||||
|
||||
//
|
||||
// Reply to client
|
||||
//
|
||||
BOOLEAN bResult =
|
||||
WriteFile(PipeHandle, // handle to pipe
|
||||
BufferToSend, // buffer to write from
|
||||
BufferSize, // number of bytes to write, include the NULL
|
||||
&cbBytes, // number of bytes written
|
||||
NULL); // not overlapped I/O
|
||||
BOOLEAN Result =
|
||||
WriteFile(PipeHandle, // handle to pipe
|
||||
BufferToSend, // buffer to write from
|
||||
BufferSize, // number of bytes to write, include the NULL
|
||||
&BytesTransferred, // number of bytes written
|
||||
NULL); // not overlapped I/O
|
||||
|
||||
if ((!bResult) || (BufferSize != cbBytes))
|
||||
if ((!Result) || (BufferSize != (INT32)BytesTransferred))
|
||||
{
|
||||
printf("Error occurred while writing to the client (%x)\n",
|
||||
printf("err, occurred while writing to the client (%x)\n",
|
||||
GetLastError());
|
||||
CloseHandle(PipeHandle);
|
||||
return FALSE;
|
||||
|
|
@ -363,15 +371,15 @@ NamedPipeClientCreatePipe(LPCSTR PipeName)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief send client message over named pipe
|
||||
* @brief Send client message over named pipe
|
||||
*
|
||||
* @param PipeHandle
|
||||
* @param BufferToSend
|
||||
* @param BufferSize
|
||||
* @return BOOLEAN
|
||||
* @param PipeHandle Handle of the named pipe
|
||||
* @param BufferToSend Buffer containing the message to send
|
||||
* @param BufferSize Size of the buffer to send
|
||||
* @return BOOLEAN TRUE if successful, FALSE otherwise
|
||||
*/
|
||||
BOOLEAN
|
||||
NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize)
|
||||
NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT32 BufferSize)
|
||||
{
|
||||
//
|
||||
// We are done connecting to the server pipe,
|
||||
|
|
@ -380,19 +388,19 @@ NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSiz
|
|||
// on handle - hPipe
|
||||
//
|
||||
|
||||
DWORD cbBytes;
|
||||
DWORD BytesTransferred;
|
||||
|
||||
//
|
||||
// Send the message to server
|
||||
//
|
||||
BOOL bResult =
|
||||
WriteFile(PipeHandle, // handle to pipe
|
||||
BufferToSend, // buffer to write from
|
||||
BufferSize, // number of bytes to write, include the NULL
|
||||
&cbBytes, // number of bytes written
|
||||
NULL); // not overlapped I/O
|
||||
BOOLEAN Result =
|
||||
WriteFile(PipeHandle, // handle to pipe
|
||||
BufferToSend, // buffer to write from
|
||||
BufferSize, // number of bytes to write, include the NULL
|
||||
&BytesTransferred, // number of bytes written
|
||||
NULL); // not overlapped I/O
|
||||
|
||||
if ((!bResult) || (BufferSize != cbBytes))
|
||||
if ((!Result) || (BufferSize != (INT32)BytesTransferred))
|
||||
{
|
||||
printf("err, occurred while writing to the server (%x)\n",
|
||||
GetLastError());
|
||||
|
|
@ -410,35 +418,40 @@ NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSiz
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Read the count of read buffer
|
||||
//
|
||||
/**
|
||||
* @brief Read a message from the server over named pipe
|
||||
*
|
||||
* @param PipeHandle Handle of the named pipe
|
||||
* @param BufferToRead Buffer to store the received message
|
||||
* @param MaximumSizeOfBuffer Maximum size of the receive buffer
|
||||
* @return UINT32 number of bytes read, or 0 on failure
|
||||
*/
|
||||
UINT32
|
||||
NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer)
|
||||
NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT32 MaximumSizeOfBuffer)
|
||||
{
|
||||
DWORD cbBytes;
|
||||
DWORD BytesTransferred;
|
||||
|
||||
//
|
||||
// Read server response
|
||||
//
|
||||
BOOL bResult = ReadFile(PipeHandle, // handle to pipe
|
||||
BufferToRead, // buffer to receive data
|
||||
MaximumSizeOfBuffer, // size of buffer
|
||||
&cbBytes, // number of bytes read
|
||||
NULL); // not overlapped I/O
|
||||
BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
|
||||
BufferToRead, // buffer to receive data
|
||||
MaximumSizeOfBuffer, // size of buffer
|
||||
&BytesTransferred, // number of bytes read
|
||||
NULL); // not overlapped I/O
|
||||
|
||||
if ((!bResult) || (0 == cbBytes))
|
||||
if ((!Result) || (0 == BytesTransferred))
|
||||
{
|
||||
printf("err, occurred while reading from the server (%x)\n",
|
||||
GetLastError());
|
||||
CloseHandle(PipeHandle);
|
||||
return NULL; // Error
|
||||
return 0; // Error
|
||||
}
|
||||
|
||||
//
|
||||
// Success
|
||||
//
|
||||
return cbBytes;
|
||||
return BytesTransferred;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -460,19 +473,19 @@ NamedPipeClientClosePipe(HANDLE PipeHandle)
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief and example of how to use named pipe as a server
|
||||
* @brief An example of how to use named pipe as a server
|
||||
*
|
||||
* @return int
|
||||
* @return INT32
|
||||
*/
|
||||
int
|
||||
INT32
|
||||
NamedPipeServerExample()
|
||||
{
|
||||
HANDLE PipeHandle;
|
||||
BOOLEAN SentMessageResult;
|
||||
UINT32 ReadBytes;
|
||||
const int BufferSize = 1024;
|
||||
char BufferToRead[BufferSize] = {0};
|
||||
char BufferToSend[BufferSize] = "test message to send from server !!!";
|
||||
HANDLE PipeHandle;
|
||||
BOOLEAN SentMessageResult;
|
||||
UINT32 ReadBytes;
|
||||
const INT32 BufferSize = 1024;
|
||||
CHAR BufferToRead[BufferSize] = {0};
|
||||
CHAR BufferToSend[BufferSize] = "test message to send from server !!!";
|
||||
|
||||
printf("create name pipe\n");
|
||||
PipeHandle = NamedPipeServerCreatePipe("\\\\.\\Pipe\\HyperDbgTests",
|
||||
|
|
@ -489,7 +502,7 @@ NamedPipeServerExample()
|
|||
printf("success!\n");
|
||||
printf("wait for the client connection\n");
|
||||
|
||||
if (!NamedPipeServerWaitForClientConntection(PipeHandle))
|
||||
if (!NamedPipeServerWaitForClientConnection(PipeHandle))
|
||||
{
|
||||
//
|
||||
// Error in connection
|
||||
|
|
@ -516,7 +529,7 @@ NamedPipeServerExample()
|
|||
SentMessageResult = NamedPipeServerSendMessageToClient(
|
||||
PipeHandle,
|
||||
BufferToSend,
|
||||
(int)strlen(BufferToSend) + 1);
|
||||
(INT32)strlen(BufferToSend) + 1);
|
||||
|
||||
if (!SentMessageResult)
|
||||
{
|
||||
|
|
@ -538,20 +551,19 @@ NamedPipeServerExample()
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief and example of how to use named pipe as a client
|
||||
* @brief An example of how to use named pipe as a client
|
||||
*
|
||||
* @return int
|
||||
* @return INT32
|
||||
*/
|
||||
int
|
||||
INT32
|
||||
NamedPipeClientExample()
|
||||
{
|
||||
HANDLE PipeHandle;
|
||||
BOOLEAN SentMessageResult;
|
||||
UINT32 ReadBytes;
|
||||
const int BufferSize = 1024;
|
||||
char Buffer[BufferSize] = "test message to send from client !!!";
|
||||
|
||||
PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
|
||||
HANDLE PipeHandle;
|
||||
BOOLEAN SentMessageResult;
|
||||
UINT32 ReadBytes;
|
||||
const INT32 BufferSize = 1024;
|
||||
CHAR Buffer[BufferSize] = "test message to send from client !!!";
|
||||
PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
|
||||
|
||||
if (!PipeHandle)
|
||||
{
|
||||
|
|
@ -562,7 +574,7 @@ NamedPipeClientExample()
|
|||
}
|
||||
|
||||
SentMessageResult =
|
||||
NamedPipeClientSendMessage(PipeHandle, Buffer, (int)strlen(Buffer) + 1);
|
||||
NamedPipeClientSendMessage(PipeHandle, Buffer, (INT32)strlen(Buffer) + 1);
|
||||
|
||||
if (!SentMessageResult)
|
||||
{
|
||||
|
|
|
|||
932
hyperdbg/hyperdbg-test/code/tests/test-codeview-rsds-parser.cpp
Normal file
932
hyperdbg/hyperdbg-test/code/tests/test-codeview-rsds-parser.cpp
Normal file
|
|
@ -0,0 +1,932 @@
|
|||
/**
|
||||
* @file test-codeview-rsds-parser.cpp
|
||||
* @author jtaw5649
|
||||
* @brief Test cases for CodeView RSDS parser helpers
|
||||
* @details
|
||||
* @version 0.19
|
||||
* @date 2026-06-02
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
static constexpr SIZE_T RsdsFixtureSize = 0x600;
|
||||
static constexpr LONG RsdsPeHeaderOffset = 0x80;
|
||||
static constexpr DWORD RsdsSectionRva = 0x1000;
|
||||
static constexpr DWORD RsdsSectionRaw = 0x200;
|
||||
static constexpr DWORD RsdsSectionSize = 0x300;
|
||||
static constexpr DWORD RsdsDebugDirectoryRva = 0x1100;
|
||||
static constexpr DWORD RsdsDebugDirectoryRaw = 0x300;
|
||||
static constexpr DWORD RsdsPayloadRva = 0x1140;
|
||||
static constexpr DWORD RsdsPayloadRaw = 0x340;
|
||||
static constexpr DWORD RsdsLoadedDebugRva = 0x280;
|
||||
static constexpr DWORD RsdsLoadedPayloadRva = 0x2c0;
|
||||
static constexpr SIZE_T RsdsHighLoadedSize = 0x22000;
|
||||
static constexpr DWORD RsdsHighLoadedDebugRva = 0x20000;
|
||||
static constexpr DWORD RsdsHighLoadedPayloadRva = 0x20100;
|
||||
static constexpr DWORD RsdsBogusRawPointer = 0xfffff000;
|
||||
|
||||
static const GUID RsdsGuid64 = {0x67452301, 0xab89, 0xefcd, {0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe}};
|
||||
static const GUID RsdsGuid32 = {0x01234567, 0x89ab, 0xcdef, {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}};
|
||||
static const GUID RsdsGuidMulti = {0xaabbccdd, 0xeeff, 0x1122, {0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa}};
|
||||
|
||||
/**
|
||||
* @brief Calculates the file offset of the optional header based on the PE header offset
|
||||
*
|
||||
* @return SIZE_T The file offset of the optional header
|
||||
*/
|
||||
static SIZE_T
|
||||
RsdsOptionalHeaderOffset()
|
||||
{
|
||||
return RsdsPeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates the file offset of the first section header based on the optional header size
|
||||
*
|
||||
* @param OptionalHeaderSize The size of the optional header, obtained from the IMAGE_FILE_HEADER
|
||||
*
|
||||
* @return SIZE_T The file offset of the first section header
|
||||
*/
|
||||
static SIZE_T
|
||||
RsdsSectionHeaderOffset(SIZE_T OptionalHeaderSize)
|
||||
{
|
||||
return RsdsOptionalHeaderOffset() + OptionalHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a minimal PE image in the provided buffer with the specified architecture
|
||||
*
|
||||
* @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
|
||||
* @param Is32Bit Whether to build a 32-bit (true) or 64-bit (false) PE image
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsBuildMinimalPe(BYTE * Buffer, BOOLEAN Is32Bit)
|
||||
{
|
||||
ZeroMemory(Buffer, RsdsFixtureSize);
|
||||
|
||||
IMAGE_DOS_HEADER * DosHeader = (IMAGE_DOS_HEADER *)Buffer;
|
||||
DosHeader->e_magic = IMAGE_DOS_SIGNATURE;
|
||||
DosHeader->e_lfanew = RsdsPeHeaderOffset;
|
||||
|
||||
BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
|
||||
*(DWORD *)NtHeaders = IMAGE_NT_SIGNATURE;
|
||||
|
||||
IMAGE_FILE_HEADER * FileHeader = (IMAGE_FILE_HEADER *)(NtHeaders + sizeof(DWORD));
|
||||
FileHeader->Machine = Is32Bit ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64;
|
||||
FileHeader->NumberOfSections = 1;
|
||||
FileHeader->SizeOfOptionalHeader = Is32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64);
|
||||
|
||||
BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
if (Is32Bit)
|
||||
{
|
||||
IMAGE_OPTIONAL_HEADER32 * OptionalHeader32 = (IMAGE_OPTIONAL_HEADER32 *)OptionalHeader;
|
||||
OptionalHeader32->Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
|
||||
OptionalHeader32->SizeOfHeaders = 0x200;
|
||||
OptionalHeader32->SizeOfImage = 0x2000;
|
||||
OptionalHeader32->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = RsdsDebugDirectoryRva;
|
||||
OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
}
|
||||
else
|
||||
{
|
||||
IMAGE_OPTIONAL_HEADER64 * OptionalHeader64 = (IMAGE_OPTIONAL_HEADER64 *)OptionalHeader;
|
||||
OptionalHeader64->Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC;
|
||||
OptionalHeader64->SizeOfHeaders = 0x200;
|
||||
OptionalHeader64->SizeOfImage = 0x2000;
|
||||
OptionalHeader64->NumberOfRvaAndSizes = IMAGE_NUMBEROF_DIRECTORY_ENTRIES;
|
||||
OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = RsdsDebugDirectoryRva;
|
||||
OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
}
|
||||
|
||||
IMAGE_SECTION_HEADER * SectionHeader = (IMAGE_SECTION_HEADER *)(Buffer + RsdsSectionHeaderOffset(FileHeader->SizeOfOptionalHeader));
|
||||
CopyMemory(SectionHeader->Name, ".rdata", sizeof(".rdata") - 1);
|
||||
SectionHeader->Misc.VirtualSize = RsdsSectionSize;
|
||||
SectionHeader->VirtualAddress = RsdsSectionRva;
|
||||
SectionHeader->SizeOfRawData = RsdsSectionSize;
|
||||
SectionHeader->PointerToRawData = RsdsSectionRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the debug directory entry in the PE image to point to the specified directory
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image
|
||||
* @param DirectoryRva The RVA of the debug directory to set
|
||||
* @param DirectorySize The size of the debug directory
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsSetDebugDirectory(BYTE * Buffer, DWORD DirectoryRva, DWORD DirectorySize)
|
||||
{
|
||||
BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
|
||||
BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
WORD Magic = *(WORD *)OptionalHeader;
|
||||
|
||||
if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
IMAGE_OPTIONAL_HEADER32 * OptionalHeader32 = (IMAGE_OPTIONAL_HEADER32 *)OptionalHeader;
|
||||
OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = DirectoryRva;
|
||||
OptionalHeader32->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = DirectorySize;
|
||||
}
|
||||
else
|
||||
{
|
||||
IMAGE_OPTIONAL_HEADER64 * OptionalHeader64 = (IMAGE_OPTIONAL_HEADER64 *)OptionalHeader;
|
||||
OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = DirectoryRva;
|
||||
OptionalHeader64->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = DirectorySize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the NumberOfRvaAndSizes field in the optional header to the specified value
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image
|
||||
* @param NumberOfRvaAndSizes The value to set for the NumberOfRvaAndSizes field
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsSetNumberOfRvaAndSizes(BYTE * Buffer, DWORD NumberOfRvaAndSizes)
|
||||
{
|
||||
BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
|
||||
BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
WORD Magic = *(WORD *)OptionalHeader;
|
||||
|
||||
if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
((IMAGE_OPTIONAL_HEADER32 *)OptionalHeader)->NumberOfRvaAndSizes = NumberOfRvaAndSizes;
|
||||
}
|
||||
else
|
||||
{
|
||||
((IMAGE_OPTIONAL_HEADER64 *)OptionalHeader)->NumberOfRvaAndSizes = NumberOfRvaAndSizes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the SizeOfImage field in the optional header to the specified value
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image
|
||||
* @param SizeOfImage The value to set for the SizeOfImage field
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsSetSizeOfImage(BYTE * Buffer, DWORD SizeOfImage)
|
||||
{
|
||||
BYTE * NtHeaders = Buffer + RsdsPeHeaderOffset;
|
||||
BYTE * OptionalHeader = NtHeaders + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
WORD Magic = *(WORD *)OptionalHeader;
|
||||
|
||||
if (Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
((IMAGE_OPTIONAL_HEADER32 *)OptionalHeader)->SizeOfImage = SizeOfImage;
|
||||
}
|
||||
else
|
||||
{
|
||||
((IMAGE_OPTIONAL_HEADER64 *)OptionalHeader)->SizeOfImage = SizeOfImage;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes an RSDS CodeView payload to the specified location in the buffer
|
||||
*
|
||||
* @param Buffer The buffer to write the payload into
|
||||
* @param RawOffset The file offset to write the payload at
|
||||
* @param Guid The GUID to include in the payload
|
||||
* @param Age The age to include in the payload
|
||||
* @param Path The path to include in the payload
|
||||
* @param IncludeNul Whether to include a NUL terminator at the end of the path
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsWritePayload(BYTE * Buffer, DWORD RawOffset, const GUID & Guid, DWORD Age, const CHAR * Path, BOOLEAN IncludeNul)
|
||||
{
|
||||
BYTE * Payload = Buffer + RawOffset;
|
||||
CopyMemory(Payload, "RSDS", sizeof(DWORD));
|
||||
CopyMemory(Payload + sizeof(DWORD), &Guid, sizeof(Guid));
|
||||
CopyMemory(Payload + sizeof(DWORD) + sizeof(GUID), &Age, sizeof(Age));
|
||||
|
||||
SIZE_T PathLength = strlen(Path);
|
||||
CopyMemory(Payload + sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD), Path, PathLength);
|
||||
if (IncludeNul)
|
||||
{
|
||||
Payload[sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + PathLength] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates the size of an RSDS CodeView payload based on the path length and whether to include a NUL terminator
|
||||
*
|
||||
* @param Path The path to be included in the payload
|
||||
* @param IncludeNul Whether to include a NUL terminator at the end of the path
|
||||
*
|
||||
* @return DWORD The size of the payload in bytes
|
||||
*/
|
||||
static DWORD
|
||||
RsdsPayloadSize(const CHAR * Path, BOOLEAN IncludeNul)
|
||||
{
|
||||
return (DWORD)(sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + strlen(Path) + (IncludeNul ? 1 : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes an IMAGE_DEBUG_DIRECTORY entry to the specified location in the buffer
|
||||
*
|
||||
* @param Buffer The buffer to write the debug entry into
|
||||
* @param EntryRawOffset The file offset to write the debug entry at
|
||||
* @param Type The Type field of the debug entry
|
||||
* @param PayloadRva The AddressOfRawData field of the debug entry
|
||||
* @param PayloadRaw The PointerToRawData field of the debug entry
|
||||
* @param PayloadSize The SizeOfData field of the debug entry
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsWriteDebugEntry(BYTE * Buffer, DWORD EntryRawOffset, DWORD Type, DWORD PayloadRva, DWORD PayloadRaw, DWORD PayloadSize)
|
||||
{
|
||||
IMAGE_DEBUG_DIRECTORY * DebugEntry = (IMAGE_DEBUG_DIRECTORY *)(Buffer + EntryRawOffset);
|
||||
ZeroMemory(DebugEntry, sizeof(*DebugEntry));
|
||||
DebugEntry->Type = Type;
|
||||
DebugEntry->SizeOfData = PayloadSize;
|
||||
DebugEntry->AddressOfRawData = PayloadRva;
|
||||
DebugEntry->PointerToRawData = PayloadRaw;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a minimal PE image with a valid RSDS debug entry in the specified buffer
|
||||
*
|
||||
* @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
|
||||
* @param Guid The GUID to include in the RSDS payload
|
||||
* @param Age The age to include in the RSDS payload
|
||||
* @param Path The path to include in the RSDS payload
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsWriteValidDebugEntry(BYTE * Buffer, const GUID & Guid, DWORD Age, const CHAR * Path)
|
||||
{
|
||||
DWORD PayloadSize = RsdsPayloadSize(Path, TRUE);
|
||||
RsdsWritePayload(Buffer, RsdsPayloadRaw, Guid, Age, Path, TRUE);
|
||||
RsdsWriteDebugEntry(Buffer, RsdsDebugDirectoryRaw, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsPayloadRva, RsdsPayloadRaw, PayloadSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a minimal PE image with a valid RSDS debug entry suitable for loaded PE parsing in the specified buffer
|
||||
*
|
||||
* @param Buffer The buffer to write the PE image into. Must be at least RsdsFixtureSize bytes
|
||||
* @param Is32Bit Whether to build a 32-bit (true) or 64-bit (false) PE image
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsBuildLoadedPe(BYTE * Buffer, BOOLEAN Is32Bit)
|
||||
{
|
||||
RsdsBuildMinimalPe(Buffer, Is32Bit);
|
||||
RsdsSetDebugDirectory(Buffer, RsdsLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a valid RSDS debug entry suitable for loaded PE parsing to the specified buffer
|
||||
*
|
||||
* @param Buffer The buffer to write the debug entry into
|
||||
* @param Guid The GUID to include in the RSDS payload
|
||||
* @param Age The age to include in the RSDS payload
|
||||
* @param Path The path to include in the RSDS payload
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
static VOID
|
||||
RsdsWriteValidLoadedDebugEntry(BYTE * Buffer, const GUID & Guid, DWORD Age, const CHAR * Path)
|
||||
{
|
||||
DWORD PayloadSize = RsdsPayloadSize(Path, TRUE);
|
||||
RsdsWritePayload(Buffer, RsdsLoadedPayloadRva, Guid, Age, Path, TRUE);
|
||||
RsdsWriteDebugEntry(Buffer, RsdsLoadedDebugRva, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsLoadedPayloadRva, RsdsBogusRawPointer, PayloadSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compares two GUIDs for equality
|
||||
*
|
||||
* @param Left The first GUID to compare
|
||||
* @param Right The second GUID to compare
|
||||
*
|
||||
* @return BOOLEAN TRUE if the GUIDs are equal, FALSE otherwise
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsGuidEquals(const GUID & Left, const GUID & Right)
|
||||
{
|
||||
return memcmp(&Left, &Right, sizeof(Left)) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to test that the RSDS parser successfully extracts the expected information from the provided buffer
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image to parse
|
||||
* @param ExpectedPdb The expected PDB file name to be extracted from the RSDS payload
|
||||
* @param ExpectedGuid The expected GUID to be extracted from the RSDS payload
|
||||
* @param ExpectedAge The expected age to be extracted from the RSDS payload
|
||||
*
|
||||
* @return BOOLEAN TRUE if the parser successfully extracted the expected information, FALSE otherwise
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsExpectSuccess(const BYTE * Buffer, const CHAR * ExpectedPdb, const GUID & ExpectedGuid, DWORD ExpectedAge)
|
||||
{
|
||||
CHAR PdbFileName[MAX_PATH] = {0};
|
||||
GUID Guid = {0};
|
||||
DWORD Age = 0;
|
||||
|
||||
return SymExtractCodeViewRsdsInfoFromPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
|
||||
strcmp(PdbFileName, ExpectedPdb) == 0 && RsdsGuidEquals(Guid, ExpectedGuid) && Age == ExpectedAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to test that the RSDS parser fails to extract information from the provided buffer and leaves output parameters unchanged
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image to parse
|
||||
*
|
||||
* @return BOOLEAN TRUE if the parser failed as expected and left output parameters unchanged, FALSE otherwise
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsExpectFailure(const BYTE * Buffer)
|
||||
{
|
||||
CHAR PdbFileName[MAX_PATH] = {'x'};
|
||||
GUID Guid = RsdsGuid64;
|
||||
GUID EmptyGuid = {0};
|
||||
DWORD Age = 0x12345678;
|
||||
|
||||
return !SymExtractCodeViewRsdsInfoFromPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
|
||||
PdbFileName[0] == '\0' && RsdsGuidEquals(Guid, EmptyGuid) && Age == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to test that the RSDS parser successfully extracts the expected information from the provided buffer when parsing as a loaded PE
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image to parse
|
||||
* @param ExpectedPdb The expected PDB file name to be extracted from the RSDS payload
|
||||
* @param ExpectedGuid The expected GUID to be extracted from the RSDS payload
|
||||
* @param ExpectedAge The expected age to be extracted from the RSDS payload
|
||||
*
|
||||
* @return BOOLEAN TRUE if the parser successfully extracted the expected information, FALSE otherwise
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsExpectLoadedSuccess(const BYTE * Buffer, const CHAR * ExpectedPdb, const GUID & ExpectedGuid, DWORD ExpectedAge)
|
||||
{
|
||||
CHAR PdbFileName[MAX_PATH] = {0};
|
||||
GUID Guid = {0};
|
||||
DWORD Age = 0;
|
||||
|
||||
return SymExtractCodeViewRsdsInfoFromLoadedPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
|
||||
strcmp(PdbFileName, ExpectedPdb) == 0 && RsdsGuidEquals(Guid, ExpectedGuid) && Age == ExpectedAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to test that the RSDS parser fails to extract information from the provided buffer when parsing as a loaded PE and leaves output parameters unchanged
|
||||
*
|
||||
* @param Buffer The buffer containing the PE image to parse
|
||||
*
|
||||
* @return BOOLEAN TRUE if the parser failed as expected and left output parameters unchanged, FALSE otherwise
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsExpectLoadedFailure(const BYTE * Buffer)
|
||||
{
|
||||
CHAR PdbFileName[MAX_PATH] = {'x'};
|
||||
GUID Guid = RsdsGuid64;
|
||||
GUID EmptyGuid = {0};
|
||||
DWORD Age = 0x12345678;
|
||||
|
||||
return !SymExtractCodeViewRsdsInfoFromLoadedPeImage(Buffer, RsdsFixtureSize, PdbFileName, sizeof(PdbFileName), &Guid, &Age) &&
|
||||
PdbFileName[0] == '\0' && RsdsGuidEquals(Guid, EmptyGuid) && Age == 0;
|
||||
}
|
||||
|
||||
// Context structure for the fake fallback function used in some test cases
|
||||
typedef struct _RSDS_FAKE_FALLBACK_CONTEXT
|
||||
{
|
||||
INT32 CallCount;
|
||||
BOOLEAN Succeed;
|
||||
} RSDS_FAKE_FALLBACK_CONTEXT, *PRSDS_FAKE_FALLBACK_CONTEXT;
|
||||
|
||||
/**
|
||||
* @brief A fake fallback function that can be used to test the behavior of the RSDS parser when a fallback is triggered
|
||||
*
|
||||
* @param Context A pointer to an RSDS_FAKE_FALLBACK_CONTEXT structure that controls the behavior of the fallback
|
||||
* @param PdbFile The output buffer to receive the PDB file name (must be at least MAX_PATH bytes)
|
||||
* @param PdbFileSize The size of the PdbFile buffer in bytes
|
||||
* @param Guid The output parameter to receive the GUID
|
||||
* @param Age The output parameter to receive the age
|
||||
*
|
||||
* @return BOOLEAN TRUE if the fallback succeeded and filled output parameters, FALSE if the fallback failed and left output parameters unchanged
|
||||
*/
|
||||
static BOOLEAN
|
||||
RsdsFakeFallback(PVOID Context, CHAR * PdbFile, SIZE_T PdbFileSize, GUID * Guid, DWORD * Age)
|
||||
{
|
||||
PRSDS_FAKE_FALLBACK_CONTEXT FallbackContext = (PRSDS_FAKE_FALLBACK_CONTEXT)Context;
|
||||
|
||||
FallbackContext->CallCount++;
|
||||
if (!FallbackContext->Succeed)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (strcpy_s(PdbFile, PdbFileSize, "fallback.pdb") != 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*Guid = RsdsGuidMulti;
|
||||
*Age = 0x2b;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Runs a series of test cases to validate the behavior of the RSDS parser helper functions
|
||||
*
|
||||
* @return BOOLEAN TRUE if all test cases passed, FALSE if any test case failed
|
||||
*/
|
||||
BOOLEAN
|
||||
TestCodeViewRsdsParser()
|
||||
{
|
||||
BYTE Buffer[RsdsFixtureSize] = {0};
|
||||
INT32 TestNum = 0;
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\valid64.pdb");
|
||||
TestNum++;
|
||||
if (RsdsExpectSuccess(Buffer, "valid64.pdb", RsdsGuid64, 7))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] valid PE32+ RSDS entry was not parsed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\unadvertised.pdb");
|
||||
RsdsSetNumberOfRvaAndSizes(Buffer, IMAGE_DIRECTORY_ENTRY_DEBUG);
|
||||
TestNum++;
|
||||
if (RsdsExpectFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] raw parser accepted an unadvertised debug directory\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, TRUE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid32, 9, "symbols/valid32.pdb");
|
||||
TestNum++;
|
||||
if (RsdsExpectSuccess(Buffer, "valid32.pdb", RsdsGuid32, 9))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] valid PE32 RSDS entry was not parsed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\valid64.pdb");
|
||||
RsdsSetDebugDirectory(Buffer, 0x3000, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
TestNum++;
|
||||
if (RsdsExpectFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] unmapped debug directory parsed successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 7, "symbols\\invalid.pdb");
|
||||
CopyMemory(Buffer + RsdsPayloadRaw, "ABCD", sizeof(DWORD));
|
||||
TestNum++;
|
||||
if (RsdsExpectFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] unsupported CodeView signature parsed successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWritePayload(Buffer, RsdsPayloadRaw, RsdsGuid64, 7, "symbols\\missing-nul.pdb", FALSE);
|
||||
RsdsWriteDebugEntry(Buffer,
|
||||
RsdsDebugDirectoryRaw,
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
RsdsPayloadRva,
|
||||
RsdsPayloadRaw,
|
||||
RsdsPayloadSize("symbols\\missing-nul.pdb", FALSE));
|
||||
TestNum++;
|
||||
if (RsdsExpectFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] RSDS path without NUL terminator parsed successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsSetDebugDirectory(Buffer, RsdsDebugDirectoryRva, sizeof(IMAGE_DEBUG_DIRECTORY) * 2);
|
||||
RsdsWriteDebugEntry(Buffer, RsdsDebugDirectoryRaw, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsPayloadRva, RsdsPayloadRaw, sizeof(DWORD));
|
||||
CopyMemory(Buffer + RsdsPayloadRaw, "NB10", sizeof(DWORD));
|
||||
RsdsWritePayload(Buffer, 0x390, RsdsGuidMulti, 11, "alt/second-valid.pdb", TRUE);
|
||||
RsdsWriteDebugEntry(Buffer,
|
||||
RsdsDebugDirectoryRaw + sizeof(IMAGE_DEBUG_DIRECTORY),
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
0x1190,
|
||||
0x390,
|
||||
RsdsPayloadSize("alt/second-valid.pdb", TRUE));
|
||||
TestNum++;
|
||||
if (RsdsExpectSuccess(Buffer, "second-valid.pdb", RsdsGuidMulti, 11))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] parser did not skip invalid first entry and parse second RSDS entry\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x21, "loaded\\loaded64.pdb");
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedSuccess(Buffer, "loaded64.pdb", RsdsGuid64, 0x21))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded PE32+ RSDS entry was not parsed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x21, "loaded\\unadvertised.pdb");
|
||||
RsdsSetNumberOfRvaAndSizes(Buffer, IMAGE_DIRECTORY_ENTRY_DEBUG);
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser accepted an unadvertised debug directory\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, TRUE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid32, 0x22, "loaded/loaded32.pdb");
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedSuccess(Buffer, "loaded32.pdb", RsdsGuid32, 0x22))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded PE32 RSDS entry was not parsed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x23, "loaded\\bogus-raw-ignored.pdb");
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedSuccess(Buffer, "bogus-raw-ignored.pdb", RsdsGuid64, 0x23))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser used bogus PointerToRawData instead of loaded RVA\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::vector<BYTE> HighLoadedBuffer(RsdsHighLoadedSize);
|
||||
RsdsBuildLoadedPe(HighLoadedBuffer.data(), FALSE);
|
||||
RsdsSetSizeOfImage(HighLoadedBuffer.data(), (DWORD)HighLoadedBuffer.size());
|
||||
RsdsSetDebugDirectory(HighLoadedBuffer.data(), RsdsHighLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
RsdsWritePayload(HighLoadedBuffer.data(), RsdsHighLoadedPayloadRva, RsdsGuid64, 0x28, "loaded\\high-rva.pdb", TRUE);
|
||||
RsdsWriteDebugEntry(HighLoadedBuffer.data(),
|
||||
RsdsHighLoadedDebugRva,
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
RsdsHighLoadedPayloadRva,
|
||||
RsdsBogusRawPointer,
|
||||
RsdsPayloadSize("loaded\\high-rva.pdb", TRUE));
|
||||
CHAR HighLoadedPdbFileName[MAX_PATH] = {0};
|
||||
GUID HighLoadedGuid = {0};
|
||||
DWORD HighLoadedAge = 0;
|
||||
TestNum++;
|
||||
if (SymExtractCodeViewRsdsInfoFromLoadedPeImage(HighLoadedBuffer.data(),
|
||||
HighLoadedBuffer.size(),
|
||||
HighLoadedPdbFileName,
|
||||
sizeof(HighLoadedPdbFileName),
|
||||
&HighLoadedGuid,
|
||||
&HighLoadedAge) &&
|
||||
strcmp(HighLoadedPdbFileName, "high-rva.pdb") == 0 && RsdsGuidEquals(HighLoadedGuid, RsdsGuid64) &&
|
||||
HighLoadedAge == 0x28)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser did not parse high-RVA RSDS data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x24, "loaded\\invalid-dir.pdb");
|
||||
RsdsSetDebugDirectory(Buffer, RsdsFixtureSize - sizeof(IMAGE_DEBUG_DIRECTORY) / 2, sizeof(IMAGE_DEBUG_DIRECTORY));
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser accepted malformed debug directory bounds\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWriteValidLoadedDebugEntry(Buffer, RsdsGuid64, 0x25, "loaded\\unsupported.pdb");
|
||||
CopyMemory(Buffer + RsdsLoadedPayloadRva, "ABCD", sizeof(DWORD));
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser accepted unsupported CodeView signature\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsWritePayload(Buffer, RsdsLoadedPayloadRva, RsdsGuid64, 0x26, "loaded\\missing-nul.pdb", FALSE);
|
||||
RsdsWriteDebugEntry(Buffer,
|
||||
RsdsLoadedDebugRva,
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
RsdsLoadedPayloadRva,
|
||||
RsdsBogusRawPointer,
|
||||
RsdsPayloadSize("loaded\\missing-nul.pdb", FALSE));
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedFailure(Buffer))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser accepted RSDS path without NUL terminator\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildLoadedPe(Buffer, FALSE);
|
||||
RsdsSetDebugDirectory(Buffer, RsdsLoadedDebugRva, sizeof(IMAGE_DEBUG_DIRECTORY) * 2);
|
||||
RsdsWriteDebugEntry(Buffer, RsdsLoadedDebugRva, IMAGE_DEBUG_TYPE_CODEVIEW, RsdsLoadedPayloadRva, RsdsBogusRawPointer, sizeof(DWORD));
|
||||
CopyMemory(Buffer + RsdsLoadedPayloadRva, "NB10", sizeof(DWORD));
|
||||
RsdsWritePayload(Buffer, 0x330, RsdsGuidMulti, 0x27, "loaded/second-loaded.pdb", TRUE);
|
||||
RsdsWriteDebugEntry(Buffer,
|
||||
RsdsLoadedDebugRva + sizeof(IMAGE_DEBUG_DIRECTORY),
|
||||
IMAGE_DEBUG_TYPE_CODEVIEW,
|
||||
0x330,
|
||||
RsdsBogusRawPointer,
|
||||
RsdsPayloadSize("loaded/second-loaded.pdb", TRUE));
|
||||
TestNum++;
|
||||
if (RsdsExpectLoadedSuccess(Buffer, "second-loaded.pdb", RsdsGuidMulti, 0x27))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] loaded parser did not skip invalid first entry and parse second RSDS entry\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CHAR SymbolServerRelativePath[MAX_PATH] = {0};
|
||||
CHAR GuidAndAgeDetails[MAX_PATH] = {0};
|
||||
CHAR SmallGuidAndAgeDetails[MAXIMUM_GUID_AND_AGE_SIZE] = {0};
|
||||
const GUID Guid = {0x01234567, 0x89ab, 0xcdef, {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}};
|
||||
TestNum++;
|
||||
if (SymFormatPdbIdentity("valid32.pdb",
|
||||
&Guid,
|
||||
0x1a,
|
||||
SymbolServerRelativePath,
|
||||
sizeof(SymbolServerRelativePath),
|
||||
GuidAndAgeDetails,
|
||||
sizeof(GuidAndAgeDetails)) &&
|
||||
strcmp(GuidAndAgeDetails, "0123456789abcdeffedcba98765432101a") == 0 &&
|
||||
strcmp(SymbolServerRelativePath, "valid32.pdb/0123456789abcdeffedcba98765432101a/valid32.pdb") == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] PDB identity formatting did not match symbol server path and GUID+age expectations\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TestNum++;
|
||||
if (SymFormatPdbIdentity("valid32.pdb",
|
||||
&Guid,
|
||||
0x1a,
|
||||
NULL,
|
||||
0,
|
||||
SmallGuidAndAgeDetails,
|
||||
sizeof(SmallGuidAndAgeDetails)) &&
|
||||
strcmp(SmallGuidAndAgeDetails, "0123456789abcdeffedcba98765432101a") == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] GUID+age identity did not fit the SDK-sized buffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RsdsBuildMinimalPe(Buffer, FALSE);
|
||||
RsdsWriteValidDebugEntry(Buffer, RsdsGuid64, 0x1c, "preferred\\preferred.pdb");
|
||||
RSDS_FAKE_FALLBACK_CONTEXT FallbackContext = {0, TRUE};
|
||||
CHAR PreferredPath[MAX_PATH] = {0};
|
||||
TestNum++;
|
||||
if (SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
PreferredPath,
|
||||
sizeof(PreferredPath),
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
strcmp(PreferredPath, "preferred.pdb/67452301ab89efcd1032547698badcfe1c/preferred.pdb") == 0 &&
|
||||
FallbackContext.CallCount == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] PE RSDS identity was not preferred over fallback identity\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FallbackContext.CallCount = 0;
|
||||
CHAR ZeroSizeOutput = 'x';
|
||||
TestNum++;
|
||||
if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
&ZeroSizeOutput,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
ZeroSizeOutput == 'x' && FallbackContext.CallCount == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] zero-sized output buffer was written or reported success\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FallbackContext.CallCount = 0;
|
||||
TestNum++;
|
||||
if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
FallbackContext.CallCount == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] identity formatting without requested output reported success or used fallback\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FallbackContext.CallCount = 0;
|
||||
CHAR SmallPdbPath[4] = {'x'};
|
||||
CHAR SmallFailureGuidAge[64] = {'x'};
|
||||
TestNum++;
|
||||
if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
NULL,
|
||||
0,
|
||||
SmallPdbPath,
|
||||
sizeof(SmallPdbPath),
|
||||
SmallFailureGuidAge,
|
||||
sizeof(SmallFailureGuidAge),
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
SmallPdbPath[0] == '\0' && SmallFailureGuidAge[0] == '\0' && FallbackContext.CallCount == 0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] output formatting failure leaked partial identity data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ZeroMemory(Buffer, sizeof(Buffer));
|
||||
FallbackContext.CallCount = 0;
|
||||
FallbackContext.Succeed = TRUE;
|
||||
CHAR FallbackPdb[MAX_PATH] = {0};
|
||||
CHAR FallbackGuidAge[MAX_PATH] = {0};
|
||||
TestNum++;
|
||||
if (SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
NULL,
|
||||
0,
|
||||
FallbackPdb,
|
||||
sizeof(FallbackPdb),
|
||||
FallbackGuidAge,
|
||||
sizeof(FallbackGuidAge),
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
strcmp(FallbackPdb, "fallback.pdb") == 0 &&
|
||||
strcmp(FallbackGuidAge, "aabbccddeeff112233445566778899aa2b") == 0 &&
|
||||
FallbackContext.CallCount == 1)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] malformed PE bytes did not use fallback identity\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FallbackContext.CallCount = 0;
|
||||
FallbackContext.Succeed = FALSE;
|
||||
CHAR FailedPath[MAX_PATH] = {'x'};
|
||||
CHAR FailedPdb[MAX_PATH] = {'x'};
|
||||
CHAR FailedGuidAge[MAX_PATH] = {'x'};
|
||||
TestNum++;
|
||||
if (!SymFormatPdbIdentityFromPeImageOrFallback(Buffer,
|
||||
RsdsFixtureSize,
|
||||
FailedPath,
|
||||
sizeof(FailedPath),
|
||||
FailedPdb,
|
||||
sizeof(FailedPdb),
|
||||
FailedGuidAge,
|
||||
sizeof(FailedGuidAge),
|
||||
RsdsFakeFallback,
|
||||
&FallbackContext) &&
|
||||
FailedPath[0] == '\0' && FailedPdb[0] == '\0' && FailedGuidAge[0] == '\0' && FallbackContext.CallCount == 1)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] fallback failure reported success or left success-looking output\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -11,132 +11,132 @@
|
|||
*/
|
||||
#include "pch.h"
|
||||
|
||||
typedef char ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as a char**
|
||||
typedef CHAR ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as CHAR**
|
||||
|
||||
/**
|
||||
* @brief Create an array of strings from a vector of strings
|
||||
* @param testCases The vector of strings to copy
|
||||
* @param TestCases The vector of strings to copy
|
||||
*
|
||||
* @return A pointer to the array of strings
|
||||
*/
|
||||
CHAR_PTR_PTR
|
||||
createTestCaseArray(const std::vector<std::string> & testCases)
|
||||
CreateTestCaseArray(const std::vector<std::string> & TestCases)
|
||||
{
|
||||
//
|
||||
// Allocate memory for the array of pointers (size: number of test cases)
|
||||
//
|
||||
CHAR_PTR_PTR testCaseArray = (CHAR_PTR_PTR)malloc(testCases.size() * sizeof(UINT64));
|
||||
CHAR_PTR_PTR TestCaseArray = (CHAR_PTR_PTR)malloc(TestCases.size() * sizeof(UINT64));
|
||||
|
||||
//
|
||||
// Allocate memory for each string and copy the content
|
||||
//
|
||||
for (size_t i = 0; i < testCases.size(); ++i)
|
||||
for (SIZE_T i = 0; i < TestCases.size(); ++i)
|
||||
{
|
||||
testCaseArray[i] = (char *)malloc(testCases[i].length() + 1); // +1 for the null terminator
|
||||
TestCaseArray[i] = (CHAR *)malloc(TestCases[i].length() + 1); // +1 for the null terminator
|
||||
|
||||
if (testCaseArray[i] == NULL)
|
||||
if (TestCaseArray[i] == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
std::strcpy(testCaseArray[i], testCases[i].c_str());
|
||||
std::strcpy(TestCaseArray[i], TestCases[i].c_str());
|
||||
}
|
||||
|
||||
return testCaseArray;
|
||||
return TestCaseArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Free the memory allocated for the test case array
|
||||
* @param testCaseArray The array of pointers to free
|
||||
* @param size The size of the array
|
||||
* @param TestCaseArray The array of pointers to free
|
||||
* @param Size The size of the array
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
freeTestCaseArray(CHAR_PTR_PTR testCaseArray, size_t size)
|
||||
FreeTestCaseArray(CHAR_PTR_PTR TestCaseArray, SIZE_T Size)
|
||||
{
|
||||
//
|
||||
// Free each string
|
||||
//
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
for (SIZE_T i = 0; i < Size; ++i)
|
||||
{
|
||||
free(testCaseArray[i]);
|
||||
free(TestCaseArray[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// Free the array of pointers
|
||||
//
|
||||
free(testCaseArray);
|
||||
free(TestCaseArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse the test cases from the file
|
||||
* @param filename The name of the file to parse
|
||||
* @param Filename The name of the file to parse
|
||||
*
|
||||
* @return A vector of pairs, where each pair contains a command and a vector of tokens
|
||||
*/
|
||||
std::vector<std::pair<std::string, std::vector<std::string>>>
|
||||
parseTestCases(const std::string & filename)
|
||||
ParseTestCases(const std::string & Filename)
|
||||
{
|
||||
std::ifstream file(filename);
|
||||
std::string line;
|
||||
std::string command;
|
||||
std::string currentToken;
|
||||
std::vector<std::string> tokens;
|
||||
std::vector<std::pair<std::string, std::vector<std::string>>> testCases;
|
||||
bool isCommand = false;
|
||||
bool addNewline = false;
|
||||
std::ifstream file(Filename);
|
||||
std::string Line;
|
||||
std::string Command;
|
||||
std::string CurrentToken;
|
||||
std::vector<std::string> Tokens;
|
||||
std::vector<std::pair<std::string, std::vector<std::string>>> TestCases;
|
||||
BOOLEAN IsCommand = FALSE;
|
||||
BOOLEAN AddNewline = FALSE;
|
||||
|
||||
const std::string tokenDelimiter = "----------------------------------";
|
||||
const std::string commandDelimiter = "_____________________________________________________________";
|
||||
const std::string TokenDelimiter = "----------------------------------";
|
||||
const std::string CommandDelimiter = "_____________________________________________________________";
|
||||
|
||||
while (std::getline(file, line))
|
||||
while (std::getline(file, Line))
|
||||
{
|
||||
if (line == commandDelimiter)
|
||||
if (Line == CommandDelimiter)
|
||||
{
|
||||
//
|
||||
// No new line is needed after this token
|
||||
//
|
||||
addNewline = false;
|
||||
AddNewline = FALSE;
|
||||
|
||||
//
|
||||
// Save the previous command and its tokens if any
|
||||
//
|
||||
if (!command.empty())
|
||||
if (!Command.empty())
|
||||
{
|
||||
if (!currentToken.empty())
|
||||
if (!CurrentToken.empty())
|
||||
{
|
||||
tokens.push_back(currentToken);
|
||||
currentToken.clear();
|
||||
Tokens.push_back(CurrentToken);
|
||||
CurrentToken.clear();
|
||||
}
|
||||
testCases.push_back({command, tokens});
|
||||
command.clear();
|
||||
tokens.clear();
|
||||
TestCases.push_back({Command, Tokens});
|
||||
Command.clear();
|
||||
Tokens.clear();
|
||||
}
|
||||
|
||||
//
|
||||
// is command is true since a command is started
|
||||
//
|
||||
isCommand = true;
|
||||
IsCommand = TRUE;
|
||||
}
|
||||
else if (line == tokenDelimiter)
|
||||
else if (Line == TokenDelimiter)
|
||||
{
|
||||
//
|
||||
// No new line is needed after this token
|
||||
//
|
||||
addNewline = false;
|
||||
AddNewline = FALSE;
|
||||
|
||||
//
|
||||
// not in command anymore
|
||||
//
|
||||
isCommand = false;
|
||||
IsCommand = FALSE;
|
||||
|
||||
//
|
||||
// If we're in the middle of collecting a token, save it
|
||||
//
|
||||
if (!currentToken.empty())
|
||||
if (!CurrentToken.empty())
|
||||
{
|
||||
tokens.push_back(currentToken);
|
||||
currentToken.clear();
|
||||
Tokens.push_back(CurrentToken);
|
||||
CurrentToken.clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -144,110 +144,110 @@ parseTestCases(const std::string & filename)
|
|||
//
|
||||
// Accumulate lines for the command or token
|
||||
//
|
||||
if (isCommand)
|
||||
if (IsCommand)
|
||||
{
|
||||
if (addNewline)
|
||||
command += "\n";
|
||||
command += line;
|
||||
if (AddNewline)
|
||||
Command += "\n";
|
||||
Command += Line;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addNewline)
|
||||
currentToken += "\n";
|
||||
currentToken += line;
|
||||
if (AddNewline)
|
||||
CurrentToken += "\n";
|
||||
CurrentToken += Line;
|
||||
}
|
||||
|
||||
addNewline = true;
|
||||
AddNewline = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Store the last command and tokens if any
|
||||
//
|
||||
if (!command.empty())
|
||||
if (!Command.empty())
|
||||
{
|
||||
if (!currentToken.empty())
|
||||
if (!CurrentToken.empty())
|
||||
{
|
||||
tokens.push_back(currentToken);
|
||||
Tokens.push_back(CurrentToken);
|
||||
}
|
||||
testCases.push_back({command, tokens});
|
||||
TestCases.push_back({Command, Tokens});
|
||||
}
|
||||
|
||||
return testCases;
|
||||
return TestCases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Count the number of occurrences of the substring "\\n" up to a specified position
|
||||
* @param str The string to search
|
||||
* @param limit The position to search up to
|
||||
* @param Str The string to search
|
||||
* @param Limit The position to search up to
|
||||
*
|
||||
* @return The number of occurrences of the substring "\\n"
|
||||
* @return INT32 The number of occurrences of the substring "\\n"
|
||||
*/
|
||||
int
|
||||
countBackslashNUpToPosition(const std::string & str, std::size_t limit)
|
||||
INT32
|
||||
CountBackslashNUpToPosition(const std::string & Str, std::size_t Limit)
|
||||
{
|
||||
int count = 0;
|
||||
std::string::size_type pos = 0;
|
||||
std::string target = "\\n";
|
||||
INT32 Count = 0;
|
||||
std::string::size_type Pos = 0;
|
||||
std::string Target = "\\n";
|
||||
|
||||
//
|
||||
// Limit the string to search within the specified range
|
||||
//
|
||||
while ((pos = str.find(target, pos)) != std::string::npos && pos < limit)
|
||||
while ((Pos = Str.find(Target, Pos)) != std::string::npos && Pos < Limit)
|
||||
{
|
||||
++count;
|
||||
pos += target.length(); // Move past the current occurrence
|
||||
++Count;
|
||||
Pos += Target.length(); // Move past the current occurrence
|
||||
}
|
||||
|
||||
return count;
|
||||
return Count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Show parsed command and tokens
|
||||
* @param testCases A vector of pairs, where each pair contains a command and a vector of tokens
|
||||
* @param failedTokenNum The number of the failed token
|
||||
* @param failedTokenPosition The position of the failed token
|
||||
* @param TestCase A pair containing a command and a vector of tokens
|
||||
* @param FailedTokenNum The number of the failed token
|
||||
* @param FailedTokenPosition The position of the failed token
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
ShowParsedCommandAndTokens(const std::pair<std::string,
|
||||
std::vector<std::string>> & testCase,
|
||||
UINT32 failedTokenNum,
|
||||
UINT32 failedTokenPosition)
|
||||
std::vector<std::string>> & TestCase,
|
||||
UINT32 FailedTokenNum,
|
||||
UINT32 FailedTokenPosition)
|
||||
{
|
||||
UINT32 tokenNum = 0;
|
||||
UINT32 TokenNum = 0;
|
||||
|
||||
//
|
||||
// Output the parsed test case
|
||||
//
|
||||
|
||||
string showingCommand = testCase.first;
|
||||
string ShowingCommand = TestCase.first;
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = showingCommand.find("\n", pos)) != std::string::npos)
|
||||
std::string::size_type Pos = 0;
|
||||
while ((Pos = ShowingCommand.find("\n", Pos)) != std::string::npos)
|
||||
{
|
||||
showingCommand.replace(pos, 1, "\\n");
|
||||
pos += 2; // Move past the newly added characters
|
||||
ShowingCommand.replace(Pos, 1, "\\n");
|
||||
Pos += 2; // Move past the newly added characters
|
||||
}
|
||||
|
||||
std::cout << "Command: \"" << showingCommand << "\"" << std::endl;
|
||||
std::cout << "Command: \"" << ShowingCommand << "\"" << std::endl;
|
||||
std::cout << "____________________________________\n";
|
||||
|
||||
std::cout << "Expected Tokens: " << std::endl;
|
||||
|
||||
for (const auto & token : testCase.second)
|
||||
for (const auto & Token : TestCase.second)
|
||||
{
|
||||
string showingToken = token;
|
||||
string ShowingToken = Token;
|
||||
|
||||
pos = 0;
|
||||
while ((pos = showingToken.find("\n", pos)) != std::string::npos)
|
||||
Pos = 0;
|
||||
while ((Pos = ShowingToken.find("\n", Pos)) != std::string::npos)
|
||||
{
|
||||
showingToken.replace(pos, 1, "\\n");
|
||||
pos += 2; // Move past the newly added characters
|
||||
ShowingToken.replace(Pos, 1, "\\n");
|
||||
Pos += 2; // Move past the newly added characters
|
||||
}
|
||||
|
||||
if (tokenNum == failedTokenNum)
|
||||
if (TokenNum == FailedTokenNum)
|
||||
{
|
||||
std::cout << " x ";
|
||||
}
|
||||
|
|
@ -256,23 +256,23 @@ ShowParsedCommandAndTokens(const std::pair<std::string,
|
|||
std::cout << " - ";
|
||||
}
|
||||
|
||||
std::cout << "\"" << showingToken << "\"" << std::endl;
|
||||
std::cout << "\"" << ShowingToken << "\"" << std::endl;
|
||||
|
||||
if (tokenNum == failedTokenNum)
|
||||
if (TokenNum == FailedTokenNum)
|
||||
{
|
||||
std::cout << " ";
|
||||
int countOfSpaces = countBackslashNUpToPosition(showingToken, failedTokenPosition);
|
||||
INT32 CountOfSpaces = CountBackslashNUpToPosition(ShowingToken, FailedTokenPosition);
|
||||
|
||||
countOfSpaces += failedTokenPosition;
|
||||
CountOfSpaces += FailedTokenPosition;
|
||||
|
||||
for (int i = 0; i < countOfSpaces; i++)
|
||||
for (INT32 i = 0; i < CountOfSpaces; i++)
|
||||
{
|
||||
std::cout << " ";
|
||||
}
|
||||
std::cout << "^" << std::endl;
|
||||
}
|
||||
|
||||
tokenNum++;
|
||||
TokenNum++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -284,17 +284,17 @@ ShowParsedCommandAndTokens(const std::pair<std::string,
|
|||
BOOLEAN
|
||||
TestCommandParser()
|
||||
{
|
||||
BOOLEAN overallResult = TRUE;
|
||||
int testNum = 0;
|
||||
CHAR filePath[MAX_PATH] = {0};
|
||||
UINT32 failedTokenNum = 0;
|
||||
UINT32 failedTokenPosition = 0;
|
||||
BOOLEAN OverallResult = TRUE;
|
||||
INT32 TestNum = 0;
|
||||
CHAR FilePath[MAX_PATH] = {0};
|
||||
UINT32 FailedTokenNum = 0;
|
||||
UINT32 FailedTokenPosition = 0;
|
||||
|
||||
//
|
||||
// Parse the test cases from the file
|
||||
// Setup the path for the filename
|
||||
//
|
||||
if (!hyperdbg_u_setup_path_for_filename(COMMAND_PARSER_TEST_CASES_FILE, filePath, MAX_PATH, TRUE))
|
||||
if (!hyperdbg_u_setup_path_for_filename(COMMAND_PARSER_TEST_CASES_FILE, FilePath, MAX_PATH, TRUE))
|
||||
{
|
||||
//
|
||||
// Error could not find the test case files
|
||||
|
|
@ -306,7 +306,7 @@ TestCommandParser()
|
|||
//
|
||||
// Parse the test cases from the file
|
||||
//
|
||||
auto testCases = parseTestCases(filePath);
|
||||
auto TestCases = ParseTestCases(FilePath);
|
||||
|
||||
//
|
||||
// Perform testing test cases with parsed file
|
||||
|
|
@ -316,32 +316,32 @@ TestCommandParser()
|
|||
//
|
||||
// Output the parsed test cases
|
||||
//
|
||||
for (const auto & testCase : testCases)
|
||||
for (const auto & TestCase : TestCases)
|
||||
{
|
||||
testNum++;
|
||||
TestNum++;
|
||||
|
||||
//
|
||||
// Create CHAR**
|
||||
//
|
||||
CHAR_PTR_PTR testCaseArray = createTestCaseArray(testCase.second);
|
||||
CHAR_PTR_PTR TestCaseArray = CreateTestCaseArray(TestCase.second);
|
||||
|
||||
//
|
||||
// Check token with actual parser
|
||||
//
|
||||
if (hyperdbg_u_test_command_parser((CHAR *)testCase.first.c_str(),
|
||||
(UINT32)testCase.second.size(),
|
||||
testCaseArray,
|
||||
&failedTokenNum,
|
||||
&failedTokenPosition))
|
||||
if (hyperdbg_u_test_command_parser((CHAR *)TestCase.first.c_str(),
|
||||
(UINT32)TestCase.second.size(),
|
||||
TestCaseArray,
|
||||
&FailedTokenNum,
|
||||
&FailedTokenPosition))
|
||||
{
|
||||
cout << "[+] Test number " << testNum << " Passed " << endl;
|
||||
cout << "[+] Test number " << TestNum << " Passed " << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Set overall result to FALSE since one of the test cases failed
|
||||
//
|
||||
overallResult = FALSE;
|
||||
OverallResult = FALSE;
|
||||
|
||||
//
|
||||
// Show parsed command and tokens
|
||||
|
|
@ -356,14 +356,14 @@ TestCommandParser()
|
|||
//
|
||||
// Show tokens
|
||||
//
|
||||
hyperdbg_u_test_command_parser_show_tokens((CHAR *)testCase.first.c_str());
|
||||
hyperdbg_u_test_command_parser_show_tokens((CHAR *)TestCase.first.c_str());
|
||||
|
||||
cout << "\n============================================================" << endl;
|
||||
|
||||
cout << "\nThe parsed command and tokens (From file):" << endl;
|
||||
ShowParsedCommandAndTokens(testCase, failedTokenNum, failedTokenPosition);
|
||||
ShowParsedCommandAndTokens(TestCase, FailedTokenNum, FailedTokenPosition);
|
||||
|
||||
cout << "\n[-] Test number " << testNum << " Failed " << endl;
|
||||
cout << "\n[-] Test number " << TestNum << " Failed " << endl;
|
||||
cout << "============================================================\n"
|
||||
<< endl;
|
||||
|
||||
|
|
@ -373,8 +373,8 @@ TestCommandParser()
|
|||
//
|
||||
// Clean up memory
|
||||
//
|
||||
freeTestCaseArray(testCaseArray, testCase.second.size());
|
||||
FreeTestCaseArray(TestCaseArray, TestCase.second.size());
|
||||
}
|
||||
|
||||
return overallResult;
|
||||
return OverallResult;
|
||||
}
|
||||
|
|
|
|||
393
hyperdbg/hyperdbg-test/code/tests/test-pe-parser.cpp
Normal file
393
hyperdbg/hyperdbg-test/code/tests/test-pe-parser.cpp
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
/**
|
||||
* @file test-pe-parser.cpp
|
||||
* @author jtaw5649
|
||||
* @brief Test cases for PE parser helpers
|
||||
* @details
|
||||
* @version 0.19
|
||||
* @date 2026-06-01
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
static constexpr SIZE_T PeFixtureSize = 0x200;
|
||||
static constexpr LONG PeHeaderOffset = 0x80;
|
||||
|
||||
/**
|
||||
* @brief Returns the byte offset of the optional header within the test fixture buffer
|
||||
*
|
||||
* The optional header immediately follows the NT signature DWORD and the
|
||||
* IMAGE_FILE_HEADER at a fixed offset determined by PeHeaderOffset.
|
||||
*
|
||||
* @return SIZE_T Byte offset from the start of the fixture buffer
|
||||
*/
|
||||
static SIZE_T
|
||||
PeOptionalHeaderOffset()
|
||||
{
|
||||
return PeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the byte offset of the section header table within the test fixture buffer
|
||||
*
|
||||
* The section table begins immediately after the optional header, whose size
|
||||
* is supplied by the caller.
|
||||
*
|
||||
* @param OptionalHeaderSize Size in bytes of the optional header (32-bit or 64-bit variant)
|
||||
*
|
||||
* @return SIZE_T Byte offset from the start of the fixture buffer
|
||||
*/
|
||||
static SIZE_T
|
||||
PeSectionHeaderOffset(SIZE_T OptionalHeaderSize)
|
||||
{
|
||||
return PeOptionalHeaderOffset() + OptionalHeaderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a little-endian 16-bit value into a byte buffer at the given offset
|
||||
*
|
||||
* @param Buffer Pointer to the destination byte buffer
|
||||
* @param Offset Byte offset within Buffer at which to write
|
||||
* @param Value 16-bit value to write in little-endian order
|
||||
*/
|
||||
static VOID
|
||||
WriteWord(BYTE * Buffer, SIZE_T Offset, WORD Value)
|
||||
{
|
||||
Buffer[Offset] = (BYTE)(Value & 0xff);
|
||||
Buffer[Offset + 1] = (BYTE)((Value >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a little-endian 32-bit value into a byte buffer at the given offset
|
||||
*
|
||||
* @param Buffer Pointer to the destination byte buffer
|
||||
* @param Offset Byte offset within Buffer at which to write
|
||||
* @param Value 32-bit value to write in little-endian order
|
||||
*/
|
||||
static VOID
|
||||
WriteDword(BYTE * Buffer, SIZE_T Offset, DWORD Value)
|
||||
{
|
||||
Buffer[Offset] = (BYTE)(Value & 0xff);
|
||||
Buffer[Offset + 1] = (BYTE)((Value >> 8) & 0xff);
|
||||
Buffer[Offset + 2] = (BYTE)((Value >> 16) & 0xff);
|
||||
Buffer[Offset + 3] = (BYTE)((Value >> 24) & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a minimal valid 64-bit PE (PE32+) fixture in the supplied buffer
|
||||
*
|
||||
* Zeroes the buffer, then writes a valid IMAGE_DOS_HEADER pointing to PeHeaderOffset,
|
||||
* an NT signature, an IMAGE_FILE_HEADER with machine type AMD64 and one section,
|
||||
* and an IMAGE_OPTIONAL_HEADER64 magic value. The result is the smallest byte
|
||||
* sequence accepted by PeImageReaderInitialize as a 64-bit PE image.
|
||||
*
|
||||
* @param Buffer Pointer to a buffer of at least PeFixtureSize bytes
|
||||
*/
|
||||
static VOID
|
||||
BuildMinimalPe64(BYTE * Buffer)
|
||||
{
|
||||
ZeroMemory(Buffer, PeFixtureSize);
|
||||
|
||||
WriteWord(Buffer, 0, IMAGE_DOS_SIGNATURE);
|
||||
WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeHeaderOffset);
|
||||
|
||||
WriteDword(Buffer, PeHeaderOffset, IMAGE_NT_SIGNATURE);
|
||||
WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, Machine), IMAGE_FILE_MACHINE_AMD64);
|
||||
WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, NumberOfSections), 1);
|
||||
WriteWord(Buffer,
|
||||
PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
|
||||
sizeof(IMAGE_OPTIONAL_HEADER64));
|
||||
WriteWord(Buffer,
|
||||
PeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER),
|
||||
IMAGE_NT_OPTIONAL_HDR64_MAGIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Builds a minimal valid 32-bit PE (PE32) fixture in the supplied buffer
|
||||
*
|
||||
* Zeroes the buffer, then writes a valid IMAGE_DOS_HEADER pointing to PeHeaderOffset,
|
||||
* an NT signature, an IMAGE_FILE_HEADER with machine type I386 and one section,
|
||||
* and an IMAGE_OPTIONAL_HEADER32 magic value. The result is the smallest byte
|
||||
* sequence accepted by PeImageReaderInitialize as a 32-bit PE image.
|
||||
*
|
||||
* @param Buffer Pointer to a buffer of at least PeFixtureSize bytes
|
||||
*/
|
||||
static VOID
|
||||
BuildMinimalPe32(BYTE * Buffer)
|
||||
{
|
||||
ZeroMemory(Buffer, PeFixtureSize);
|
||||
|
||||
WriteWord(Buffer, 0, IMAGE_DOS_SIGNATURE);
|
||||
WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeHeaderOffset);
|
||||
|
||||
WriteDword(Buffer, PeHeaderOffset, IMAGE_NT_SIGNATURE);
|
||||
WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, Machine), IMAGE_FILE_MACHINE_I386);
|
||||
WriteWord(Buffer, PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, NumberOfSections), 1);
|
||||
WriteWord(Buffer,
|
||||
PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
|
||||
sizeof(IMAGE_OPTIONAL_HEADER32));
|
||||
WriteWord(Buffer,
|
||||
PeHeaderOffset + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER),
|
||||
IMAGE_NT_OPTIONAL_HDR32_MAGIC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the SizeOfHeaders field in the PE64 optional header of a fixture buffer
|
||||
*
|
||||
* Computes the field offset within IMAGE_OPTIONAL_HEADER64 and writes a 32-bit
|
||||
* little-endian value at that position.
|
||||
*
|
||||
* @param Buffer Pointer to a fixture buffer previously initialised by BuildMinimalPe64
|
||||
* @param SizeOfHeaders Value to write into the SizeOfHeaders field
|
||||
*/
|
||||
static VOID
|
||||
SetPe64OptionalHeaderSizeOfHeaders(BYTE * Buffer, DWORD SizeOfHeaders)
|
||||
{
|
||||
SIZE_T Offset = PeOptionalHeaderOffset() + offsetof(IMAGE_OPTIONAL_HEADER64, SizeOfHeaders);
|
||||
|
||||
WriteDword(Buffer, Offset, SizeOfHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to the first section header in a fixture buffer
|
||||
*
|
||||
* Computes the section header table offset using OptionalHeaderSize and casts
|
||||
* the corresponding location in Buffer to IMAGE_SECTION_HEADER *.
|
||||
*
|
||||
* @param Buffer Pointer to a fixture buffer
|
||||
* @param OptionalHeaderSize Size in bytes of the optional header used by the fixture
|
||||
*
|
||||
* @return IMAGE_SECTION_HEADER* Pointer to the first section header within the buffer
|
||||
*/
|
||||
static IMAGE_SECTION_HEADER *
|
||||
GetFixtureSectionHeader(BYTE * Buffer, SIZE_T OptionalHeaderSize)
|
||||
{
|
||||
return (IMAGE_SECTION_HEADER *)(Buffer + PeSectionHeaderOffset(OptionalHeaderSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the .text section header in a fixture buffer
|
||||
*
|
||||
* Zeroes the first section header slot, writes the name ".text", and sets
|
||||
* the virtual address, virtual size, raw data pointer, and raw data size
|
||||
* fields to the supplied values.
|
||||
*
|
||||
* @param Buffer Pointer to a fixture buffer
|
||||
* @param OptionalHeaderSize Size in bytes of the optional header used by the fixture
|
||||
* @param VirtualAddress RVA at which the section is loaded
|
||||
* @param VirtualSize Virtual size of the section
|
||||
* @param PointerToRawData Raw file offset of the section data
|
||||
* @param SizeOfRawData Size of the raw data on disk
|
||||
*/
|
||||
static VOID
|
||||
ConfigureTextSection(BYTE * Buffer, SIZE_T OptionalHeaderSize, DWORD VirtualAddress, DWORD VirtualSize, DWORD PointerToRawData, DWORD SizeOfRawData)
|
||||
{
|
||||
IMAGE_SECTION_HEADER * SectionHeader = GetFixtureSectionHeader(Buffer, OptionalHeaderSize);
|
||||
|
||||
ZeroMemory(SectionHeader, sizeof(*SectionHeader));
|
||||
CopyMemory(SectionHeader->Name, ".text", sizeof(".text") - 1);
|
||||
SectionHeader->Misc.VirtualSize = VirtualSize;
|
||||
SectionHeader->VirtualAddress = VirtualAddress;
|
||||
SectionHeader->SizeOfRawData = SizeOfRawData;
|
||||
SectionHeader->PointerToRawData = PointerToRawData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Runs all PE parser unit tests and reports pass/fail results
|
||||
*
|
||||
* Each numbered test case exercises a distinct behaviour of the PE image reader:
|
||||
* 1. A valid PE32+ image initialises successfully and reports 64-bit.
|
||||
* 2. A valid PE32 image initialises successfully and reports 32-bit.
|
||||
* 3. A corrupt DOS magic causes initialisation to fail.
|
||||
* 4. An optional header that is one byte too small causes initialisation to fail.
|
||||
* 5. An e_lfanew value that points past the buffer causes initialisation to fail.
|
||||
* 6. A valid section RVA maps to the correct raw file offset.
|
||||
* 7. Header-range RVA resolution is enforced at SizeOfHeaders boundaries.
|
||||
* 8. An 8-byte section name is always returned null-terminated.
|
||||
* 9. An RVA whose raw mapping extends outside the file is rejected.
|
||||
*
|
||||
* @return BOOLEAN TRUE if all tests pass, FALSE if any test fails
|
||||
*/
|
||||
BOOLEAN
|
||||
TestPeParser()
|
||||
{
|
||||
BOOLEAN OverallResult = TRUE;
|
||||
INT32 TestNum = 0;
|
||||
BYTE Buffer[PeFixtureSize] = {0};
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
|
||||
if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && !PeImageReaderIs32Bit(&Reader))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] valid PE64 did not initialize as PE32+\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe32(Buffer);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
|
||||
if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) && PeImageReaderIs32Bit(&Reader))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] valid PE32 did not initialize as PE32\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
WriteWord(Buffer, 0, 0);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
|
||||
if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] invalid DOS magic initialized successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
WriteWord(Buffer,
|
||||
PeHeaderOffset + sizeof(DWORD) + offsetof(IMAGE_FILE_HEADER, SizeOfOptionalHeader),
|
||||
sizeof(IMAGE_OPTIONAL_HEADER64) - 1);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
|
||||
if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] truncated optional header initialized successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
WriteDword(Buffer, offsetof(IMAGE_DOS_HEADER, e_lfanew), PeFixtureSize);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
|
||||
if (!PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] invalid e_lfanew initialized successfully\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
|
||||
ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x50, 0x1c0, 0x40);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
SIZE_T FileOffset = 0;
|
||||
|
||||
if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
|
||||
PeImageReaderRvaToFileOffset(&Reader, 0x1010, 4, &FileOffset) && FileOffset == 0x1d0)
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] valid section RVA did not map to raw file offset\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
SIZE_T FileOffset = 0;
|
||||
|
||||
if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
|
||||
PeImageReaderRvaToFileOffset(&Reader, 0x20, 4, &FileOffset) && FileOffset == 0x20 &&
|
||||
!PeImageReaderRvaToFileOffset(&Reader, 0x1be, 4, &FileOffset))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] header RVA bounds were not enforced\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
TestNum++;
|
||||
{
|
||||
IMAGE_SECTION_HEADER SectionHeader = {0};
|
||||
CHAR Name[9];
|
||||
|
||||
FillMemory(Name, sizeof(Name), 'X');
|
||||
CopyMemory(SectionHeader.Name, "ABCDEFGH", IMAGE_SIZEOF_SHORT_NAME);
|
||||
if (PeImageReaderGetSectionName(&SectionHeader, Name, sizeof(Name)) &&
|
||||
strcmp(Name, "ABCDEFGH") == 0 && Name[IMAGE_SIZEOF_SHORT_NAME] == '\0')
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] 8-byte section name was not null-terminated\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
BuildMinimalPe64(Buffer);
|
||||
SetPe64OptionalHeaderSizeOfHeaders(Buffer, 0x1c0);
|
||||
ConfigureTextSection(Buffer, sizeof(IMAGE_OPTIONAL_HEADER64), 0x1000, 0x40, 0x300, 0x20);
|
||||
TestNum++;
|
||||
{
|
||||
PE_IMAGE_READER Reader = {0};
|
||||
SIZE_T FileOffset = 0;
|
||||
|
||||
if (PeImageReaderInitialize(Buffer, sizeof(Buffer), &Reader) &&
|
||||
!PeImageReaderRvaToFileOffset(&Reader, 0x1000, 1, &FileOffset))
|
||||
{
|
||||
printf("[+] Test number %d Passed\n", TestNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("[-] Test number %d Failed\n", TestNum);
|
||||
printf("[x] RVA mapping accepted raw pointer outside file\n");
|
||||
OverallResult = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return OverallResult;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* @file test-semanitc-scripts.cpp
|
||||
* @file test-semantic-scripts.cpp
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Perform test on semantic scripts
|
||||
* @details
|
||||
|
|
@ -21,7 +21,7 @@ namespace fs = std::filesystem;
|
|||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
|
||||
ReadDirectoryAndTestSemanticTestCases(const CHAR * ScriptSemanticPath)
|
||||
{
|
||||
//
|
||||
// Iterate through the directory
|
||||
|
|
@ -38,7 +38,7 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
|
|||
//
|
||||
// Get the file path
|
||||
//
|
||||
std::string filePath = entry.path().string();
|
||||
std::string FilePath = entry.path().string();
|
||||
|
||||
//
|
||||
// Output the file name
|
||||
|
|
@ -48,10 +48,10 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
|
|||
//
|
||||
// Open the file and read its contents
|
||||
//
|
||||
std::ifstream file(filePath);
|
||||
if (file.is_open())
|
||||
std::ifstream File(FilePath);
|
||||
if (File.is_open())
|
||||
{
|
||||
std::string content((std::istreambuf_iterator<char>(file)),
|
||||
std::string Content((std::istreambuf_iterator<char>(File)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
//
|
||||
|
|
@ -64,18 +64,18 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
|
|||
//
|
||||
// Run the test case command
|
||||
//
|
||||
hyperdbg_u_run_command((CHAR *)content.c_str());
|
||||
hyperdbg_u_run_command((CHAR *)Content.c_str());
|
||||
|
||||
std::cout << "--------------------------------------------" << std::endl;
|
||||
|
||||
//
|
||||
// Close the file
|
||||
//
|
||||
file.close();
|
||||
File.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not open file: " << filePath << std::endl;
|
||||
std::cerr << "Could not open file: " << FilePath << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -94,8 +94,8 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
|
|||
BOOLEAN
|
||||
TestSemanticScripts()
|
||||
{
|
||||
int testNum = 0;
|
||||
CHAR dirPath[MAX_PATH] = {0};
|
||||
INT32 TestNum = 0;
|
||||
CHAR dirPath[MAX_PATH] = {0};
|
||||
|
||||
//
|
||||
// Parse the semantic script test cases from the file
|
||||
|
|
@ -122,7 +122,7 @@ TestSemanticScripts()
|
|||
//
|
||||
// Run test cases
|
||||
//
|
||||
ReadDirectoryAndTestSemanticTestcases(dirPath);
|
||||
ReadDirectoryAndTestSemanticTestCases(dirPath);
|
||||
|
||||
//
|
||||
// Close the connection
|
||||
|
|
|
|||
|
|
@ -11,28 +11,48 @@
|
|||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Convert a UINT64 value to a hex string
|
||||
*
|
||||
* @param Value the value to convert
|
||||
* @return std::string the hex string representation
|
||||
*/
|
||||
std::string
|
||||
Uint64ToString(UINT64 value)
|
||||
Uint64ToString(UINT64 Value)
|
||||
{
|
||||
ostringstream Os;
|
||||
Os << setw(16) << setfill('0') << hex << value;
|
||||
Os << setw(16) << setfill('0') << hex << Value;
|
||||
return Os.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replace the first occurrence of a substring in a string
|
||||
*
|
||||
* @param Str the string to modify
|
||||
* @param From the substring to search for
|
||||
* @param To the replacement substring
|
||||
* @return BOOLEAN TRUE if the replacement was made, FALSE otherwise
|
||||
*/
|
||||
BOOLEAN
|
||||
StringReplace(std::string & str, const std::string & from, const std::string & to)
|
||||
StringReplace(std::string & Str, const std::string & From, const std::string & To)
|
||||
{
|
||||
size_t start_pos = str.find(from);
|
||||
if (start_pos == string::npos)
|
||||
SIZE_T StartPos = Str.find(From);
|
||||
if (StartPos == string::npos)
|
||||
return FALSE;
|
||||
str.replace(start_pos, from.length(), to);
|
||||
Str.replace(StartPos, From.length(), To);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a C-string to a std::string
|
||||
*
|
||||
* @param Str the C-string to convert
|
||||
* @return std::string the resulting string object
|
||||
*/
|
||||
std::string
|
||||
ConvertToString(char * Str)
|
||||
ConvertToString(CHAR * Str)
|
||||
{
|
||||
string s(Str);
|
||||
string Result(Str);
|
||||
|
||||
return s;
|
||||
return Result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ HANDLE
|
|||
NamedPipeServerCreatePipe(LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 InputBufferSize);
|
||||
|
||||
BOOLEAN
|
||||
NamedPipeServerWaitForClientConntection(HANDLE PipeHandle);
|
||||
NamedPipeServerWaitForClientConnection(HANDLE PipeHandle);
|
||||
|
||||
UINT32
|
||||
NamedPipeServerReadClientMessage(HANDLE PipeHandle, char * BufferToSave, int MaximumReadBufferLength);
|
||||
NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR * BufferToSave, INT32 MaximumReadBufferLength);
|
||||
|
||||
BOOLEAN
|
||||
NamedPipeServerSendMessageToClient(HANDLE PipeHandle,
|
||||
char * BufferToSend,
|
||||
int BufferSize);
|
||||
CHAR * BufferToSend,
|
||||
INT32 BufferSize);
|
||||
|
||||
VOID
|
||||
NamedPipeServerCloseHandle(HANDLE PipeHandle);
|
||||
|
|
@ -40,10 +40,10 @@ HANDLE
|
|||
NamedPipeClientCreatePipe(LPCSTR PipeName);
|
||||
|
||||
BOOLEAN
|
||||
NamedPipeClientSendMessage(HANDLE PipeHandle, char * BufferToSend, int BufferSize);
|
||||
NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR * BufferToSend, INT32 BufferSize);
|
||||
|
||||
UINT32
|
||||
NamedPipeClientReadMessage(HANDLE PipeHandle, char * BufferToRead, int MaximumSizeOfBuffer);
|
||||
NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR * BufferToRead, INT32 MaximumSizeOfBuffer);
|
||||
|
||||
VOID
|
||||
NamedPipeClientClosePipe(HANDLE PipeHandle);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ TestCase(std::vector<std::string> & TestCase);
|
|||
//////////////////////////////////////////////////
|
||||
|
||||
extern "C" {
|
||||
extern void inline AsmTest();
|
||||
extern VOID inline AsmTest();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
|
@ -37,10 +37,10 @@ TestCreateLookupTable(HANDLE PipeHandle, PVOID KernelInformation, UINT32 KernelI
|
|||
//////////////////////////////////////////////////
|
||||
|
||||
std::string
|
||||
Uint64ToString(UINT64 value);
|
||||
Uint64ToString(UINT64 Value);
|
||||
|
||||
BOOLEAN
|
||||
StringReplace(std::string & str, const std::string & from, const std::string & to);
|
||||
StringReplace(std::string & Str, const std::string & From, const std::string & To);
|
||||
|
||||
std::string
|
||||
ConvertToString(char * Str);
|
||||
ConvertToString(CHAR * Str);
|
||||
|
|
|
|||
|
|
@ -18,5 +18,11 @@
|
|||
BOOLEAN
|
||||
TestCommandParser();
|
||||
|
||||
BOOLEAN
|
||||
TestPeParser();
|
||||
|
||||
BOOLEAN
|
||||
TestCodeViewRsdsParser();
|
||||
|
||||
BOOLEAN
|
||||
TestSemanticScripts();
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
|
|
@ -103,20 +103,27 @@
|
|||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\include\components\pe\code\pe-image-reader.cpp" />
|
||||
<ClCompile Include="code\hardware\hwdbg-tests.cpp" />
|
||||
<ClCompile Include="..\symbol-parser\code\codeview-rsds.cpp" />
|
||||
<ClCompile Include="..\symbol-parser\code\pdb-identity.cpp" />
|
||||
<ClCompile Include="code\main.cpp" />
|
||||
<ClCompile Include="code\namedpipe.cpp" />
|
||||
<ClCompile Include="code\tests\test-codeview-rsds-parser.cpp" />
|
||||
<ClCompile Include="code\tests\test-pe-parser.cpp" />
|
||||
<ClCompile Include="code\tests\test-parser.cpp" />
|
||||
<ClCompile Include="code\tests\test-semantic-scripts.cpp" />
|
||||
<ClCompile Include="code\tools.cpp" />
|
||||
<ClCompile Include="pch.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\platform\user\header\Environment.h" />
|
||||
<ClInclude Include="..\include\components\pe\header\pe-image-reader.h" />
|
||||
<ClInclude Include="header\hwdbg-tests.h" />
|
||||
<ClInclude Include="header\namedpipe.h" />
|
||||
<ClInclude Include="header\routines.h" />
|
||||
<ClInclude Include="header\testcases.h" />
|
||||
<ClInclude Include="..\symbol-parser\header\codeview-rsds.h" />
|
||||
<ClInclude Include="..\symbol-parser\header\pdb-identity.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -21,11 +21,29 @@
|
|||
<Filter Include="code\hardware">
|
||||
<UniqueIdentifier>{18515e99-bdbe-465f-9c92-58dc89591116}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\components">
|
||||
<UniqueIdentifier>{4905a2c5-31b5-4b16-9f84-d2b3b39726d3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\components\pe">
|
||||
<UniqueIdentifier>{2835e8e0-5525-473b-ae43-c498674fb42e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\components">
|
||||
<UniqueIdentifier>{b36455ac-6726-4c17-903c-3c3e3de1b783}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\components\pe">
|
||||
<UniqueIdentifier>{b3920039-7e86-412e-bf10-8a5a7946e102}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="code\tests\test-parser.cpp">
|
||||
<Filter>code\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\tests\test-pe-parser.cpp">
|
||||
<Filter>code\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\tests\test-codeview-rsds-parser.cpp">
|
||||
<Filter>code\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\namedpipe.cpp">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -41,9 +59,18 @@
|
|||
<ClCompile Include="code\hardware\hwdbg-tests.cpp">
|
||||
<Filter>code\hardware</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\symbol-parser\code\codeview-rsds.cpp">
|
||||
<Filter>code\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\symbol-parser\code\pdb-identity.cpp">
|
||||
<Filter>code\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\components\pe\code\pe-image-reader.cpp">
|
||||
<Filter>code\components\pe</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="header\namedpipe.h">
|
||||
|
|
@ -52,9 +79,6 @@
|
|||
<ClInclude Include="header\routines.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\platform\user\header\Environment.h">
|
||||
<Filter>header\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\testcases.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -64,10 +88,19 @@
|
|||
<ClInclude Include="pch.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\components\pe\header\pe-image-reader.h">
|
||||
<Filter>header\components\pe</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\symbol-parser\header\codeview-rsds.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\symbol-parser\header\pdb-identity.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MASM Include="code\assembly\asm-test.asm">
|
||||
<Filter>code\assembly</Filter>
|
||||
</MASM>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ using namespace std;
|
|||
//
|
||||
// Environment headers
|
||||
//
|
||||
#include "platform/user/header/Environment.h"
|
||||
#include "platform/general/header/Environment.h"
|
||||
|
||||
//
|
||||
// General Headers
|
||||
|
|
@ -34,20 +34,32 @@ using namespace std;
|
|||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <strsafe.h>
|
||||
|
||||
//
|
||||
// SDK and config headers
|
||||
//
|
||||
#include "SDK/HyperDbgSdk.h"
|
||||
#include "config/Definition.h"
|
||||
|
||||
//
|
||||
// Program Defined Headers
|
||||
//
|
||||
#include "SDK/HyperDbgSdk.h"
|
||||
#include "config/Definition.h"
|
||||
#include "../hyperdbg-test/header/namedpipe.h"
|
||||
#include "../hyperdbg-test/header/routines.h"
|
||||
#include "../hyperdbg-test/header/testcases.h"
|
||||
#include "header/namedpipe.h"
|
||||
#include "header/routines.h"
|
||||
#include "header/testcases.h"
|
||||
#include "header/pdb-identity.h"
|
||||
#include "header/codeview-rsds.h"
|
||||
|
||||
//
|
||||
// Components
|
||||
//
|
||||
#include "../include/components/pe/header/pe-image-reader.h"
|
||||
|
||||
//
|
||||
// Hardware Debugger Headers
|
||||
//
|
||||
#include "../hyperdbg-test/header/hwdbg-tests.h"
|
||||
#include "header/hwdbg-tests.h"
|
||||
|
||||
//
|
||||
// import libhyperdbg
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32602.215
|
||||
# Visual Studio Version 18
|
||||
VisualStudioVersion = 18.7.11911.148
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-cli", "hyperdbg-cli\hyperdbg-cli.vcxproj", "{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
|
|
@ -60,7 +60,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "headers", "headers", "{D67D
|
|||
include\SDK\Headers\Events.h = include\SDK\Headers\Events.h
|
||||
include\SDK\Headers\HardwareDebugger.h = include\SDK\Headers\HardwareDebugger.h
|
||||
include\SDK\Headers\Ioctls.h = include\SDK\Headers\Ioctls.h
|
||||
include\SDK\headers\LbrDefinitions.h = include\SDK\headers\LbrDefinitions.h
|
||||
include\SDK\headers\Pcie.h = include\SDK\headers\Pcie.h
|
||||
include\SDK\headers\PortableExecutable.h = include\SDK\headers\PortableExecutable.h
|
||||
include\SDK\headers\PtDefinitions.h = include\SDK\headers\PtDefinitions.h
|
||||
include\SDK\Headers\RequestStructures.h = include\SDK\Headers\RequestStructures.h
|
||||
include\SDK\Headers\ScriptEngineCommonDefinitions.h = include\SDK\Headers\ScriptEngineCommonDefinitions.h
|
||||
include\SDK\Headers\Symbols.h = include\SDK\Headers\Symbols.h
|
||||
|
|
@ -87,6 +90,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "imports", "imports", "{B3D9
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperkd", "hyperkd\hyperkd.vcxproj", "{AFDD7028-1ED9-442E-8A3D-01CFA3AA1CAA}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{360E54B1-0B92-4BCA-8111-4BF384292621} = {360E54B1-0B92-4BCA-8111-4BF384292621}
|
||||
{9FA45E25-DAEB-4C2D-806C-7908A180195D} = {9FA45E25-DAEB-4C2D-806C-7908A180195D}
|
||||
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}
|
||||
{BB17323A-2460-4AE1-8AFE-B367400B934F} = {BB17323A-2460-4AE1-8AFE-B367400B934F}
|
||||
EndProjectSection
|
||||
|
|
@ -97,6 +102,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "modules", "modules", "{13E4
|
|||
ProjectSection(SolutionItems) = preProject
|
||||
include\SDK\modules\HyperEvade.h = include\SDK\modules\HyperEvade.h
|
||||
include\SDK\Modules\HyperLog.h = include\SDK\Modules\HyperLog.h
|
||||
include\SDK\modules\HyperPerf.h = include\SDK\modules\HyperPerf.h
|
||||
include\SDK\modules\HyperTrace.h = include\SDK\modules\HyperTrace.h
|
||||
include\SDK\Modules\VMM.h = include\SDK\Modules\VMM.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
|
@ -145,20 +152,49 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{D0E5A2
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{6498728B-D9B0-4CAB-A9E3-ACE5BC371010}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\kernel\code\Mem.c = include\platform\kernel\code\Mem.c
|
||||
include\platform\kernel\code\PlatformBroadcast.c = include\platform\kernel\code\PlatformBroadcast.c
|
||||
include\platform\kernel\code\PlatformCpu.c = include\platform\kernel\code\PlatformCpu.c
|
||||
include\platform\kernel\code\PlatformDbg.c = include\platform\kernel\code\PlatformDbg.c
|
||||
include\platform\kernel\code\PlatformDpc.c = include\platform\kernel\code\PlatformDpc.c
|
||||
include\platform\kernel\code\PlatformEvent.c = include\platform\kernel\code\PlatformEvent.c
|
||||
include\platform\kernel\code\PlatformIntrinsics.c = include\platform\kernel\code\PlatformIntrinsics.c
|
||||
include\platform\kernel\code\PlatformIntrinsicsVmx.c = include\platform\kernel\code\PlatformIntrinsicsVmx.c
|
||||
include\platform\kernel\code\PlatformIo.c = include\platform\kernel\code\PlatformIo.c
|
||||
include\platform\kernel\code\PlatformIrql.c = include\platform\kernel\code\PlatformIrql.c
|
||||
include\platform\kernel\code\PlatformMem.c = include\platform\kernel\code\PlatformMem.c
|
||||
include\platform\kernel\code\PlatformProcess.c = include\platform\kernel\code\PlatformProcess.c
|
||||
include\platform\kernel\code\PlatformSpinlock.c = include\platform\kernel\code\PlatformSpinlock.c
|
||||
include\platform\kernel\code\PlatformTime.c = include\platform\kernel\code\PlatformTime.c
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{AA41FFF1-A730-433E-8D26-13DA5B653825}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\kernel\header\Environment.h = include\platform\kernel\header\Environment.h
|
||||
include\platform\kernel\header\Mem.h = include\platform\kernel\header\Mem.h
|
||||
include\platform\kernel\header\pch.h = include\platform\kernel\header\pch.h
|
||||
include\platform\kernel\header\PlatformBroadcast.h = include\platform\kernel\header\PlatformBroadcast.h
|
||||
include\platform\kernel\header\PlatformCpu.h = include\platform\kernel\header\PlatformCpu.h
|
||||
include\platform\kernel\header\PlatformDbg.h = include\platform\kernel\header\PlatformDbg.h
|
||||
include\platform\kernel\header\PlatformDpc.h = include\platform\kernel\header\PlatformDpc.h
|
||||
include\platform\kernel\header\PlatformEvent.h = include\platform\kernel\header\PlatformEvent.h
|
||||
include\platform\kernel\header\PlatformIntrinsics.h = include\platform\kernel\header\PlatformIntrinsics.h
|
||||
include\platform\kernel\header\PlatformIntrinsicsVmx.h = include\platform\kernel\header\PlatformIntrinsicsVmx.h
|
||||
include\platform\kernel\header\PlatformIo.h = include\platform\kernel\header\PlatformIo.h
|
||||
include\platform\kernel\header\PlatformIrql.h = include\platform\kernel\header\PlatformIrql.h
|
||||
include\platform\kernel\header\PlatformMem.h = include\platform\kernel\header\PlatformMem.h
|
||||
include\platform\kernel\header\PlatformModuleInfo.h = include\platform\kernel\header\PlatformModuleInfo.h
|
||||
include\platform\kernel\header\PlatformProcess.h = include\platform\kernel\header\PlatformProcess.h
|
||||
include\platform\kernel\header\PlatformSpinlock.h = include\platform\kernel\header\PlatformSpinlock.h
|
||||
include\platform\kernel\header\PlatformTime.h = include\platform\kernel\header\PlatformTime.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{4BF590C3-1032-4DD2-BF87-BB9E5781977C}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\user\code\platform-intrinsics.c = include\platform\user\code\platform-intrinsics.c
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{DBE32379-8D5A-4454-A1B6-ACC407881898}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\user\header\Environment.h = include\platform\user\header\Environment.h
|
||||
include\platform\user\header\platform-intrinsics.h = include\platform\user\header\platform-intrinsics.h
|
||||
include\platform\user\header\Windows.h = include\platform\user\header\Windows.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{3C04357D-93B5-4472-94BB-8D22A1EB16DB}"
|
||||
|
|
@ -173,6 +209,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{947577
|
|||
include\SDK\imports\kernel\HyperDbgHyperEvade.h = include\SDK\imports\kernel\HyperDbgHyperEvade.h
|
||||
include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h = include\SDK\Imports\Kernel\HyperDbgHyperLogImports.h
|
||||
include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h = include\SDK\Imports\Kernel\HyperDbgHyperLogIntrinsics.h
|
||||
include\SDK\imports\kernel\HyperDbgHyperPerf.h = include\SDK\imports\kernel\HyperDbgHyperPerf.h
|
||||
include\SDK\imports\kernel\HyperDbgHyperTrace.h = include\SDK\imports\kernel\HyperDbgHyperTrace.h
|
||||
include\SDK\Imports\Kernel\HyperDbgVmmImports.h = include\SDK\Imports\Kernel\HyperDbgVmmImports.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
|
@ -214,6 +252,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg_app", "..\examples
|
|||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperevade", "hyperevade\hyperevade.vcxproj", "{B226530A-14B1-40AC-B82E-D9057400E7EE}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D} = {AFDE69E9-EE3D-470E-8407-C1F0D98F9E3D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "hyper-v", "hyper-v", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
|
|
@ -226,6 +267,71 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{035508
|
|||
include\config\Definition.h = include\config\Definition.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hypertrace", "hypertrace\hypertrace.vcxproj", "{9FA45E25-DAEB-4C2D-806C-7908A180195D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "general", "general", "{17652C16-00A0-40D4-A227-697E595DE053}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{9E1A2FAF-696A-4CA7-8C2E-F6B80107A143}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\general\header\Environment.h = include\platform\general\header\Environment.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "linux", "linux", "{63D4BB7A-C404-4A35-A302-20034DD8BA77}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "mock", "mock", "{770B65D6-5307-478C-A9EB-3E4A64B67225}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{848FE945-4F37-4B5B-98C8-F22CA3AA7184}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "user", "user", "{D3722A82-0A54-4172-A0C1-1EA6500E9F1E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
linux\mock\user\Makefile = linux\mock\user\Makefile
|
||||
linux\mock\user\mock.c = linux\mock\user\mock.c
|
||||
linux\mock\user\pch.h = linux\mock\user\pch.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "kernel", "kernel", "{09E02C0A-6A6C-408A-8136-C787FDC58A5F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
linux\mock\kernel\Makefile = linux\mock\kernel\Makefile
|
||||
linux\mock\kernel\mock.c = linux\mock\kernel\mock.c
|
||||
linux\mock\kernel\pch.h = linux\mock\kernel\pch.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows-only", "windows-only", "{C95E342A-9622-4351-8177-CDA43A52E7B2}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\user\header\windows-only\windows-privilege.h = include\platform\user\header\windows-only\windows-privilege.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "windows-only", "windows-only", "{45ABB14F-86B9-40BE-9C0F-213653CE6A93}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\platform\user\code\windows-only\windows-privilege.c = include\platform\user\code\windows-only\windows-privilege.c
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "callback", "callback", "{1AA10217-07BF-490B-A688-1D1D6A267D52}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{78821DCF-DCFE-45B7-A9DD-3543BDF1FB9E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\components\callback\hyperlog\code\HyperLogCallback.c = include\components\callback\hyperlog\code\HyperLogCallback.c
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{AD02B952-0D75-47FE-8FF7-18B3E081E2C1}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\components\callback\hyperlog\header\HyperLogCallback.h = include\components\callback\hyperlog\header\HyperLogCallback.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pe", "pe", "{9A0232BB-B06B-47EE-A096-E7B475956437}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code", "code", "{824DF7C7-18B5-48DE-99D7-AD6B612D6204}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\components\pe\code\pe-image-reader.cpp = include\components\pe\code\pe-image-reader.cpp
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "header", "header", "{CA2D9C24-F90A-48ED-8ABC-F296674EA2B7}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
include\components\pe\header\pe-image-reader.h = include\components\pe\header\pe-image-reader.h
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperperf", "hyperperf\hyperperf.vcxproj", "{360E54B1-0B92-4BCA-8111-4BF384292621}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
debug|x64 = debug|x64
|
||||
|
|
@ -279,6 +385,14 @@ Global
|
|||
{B226530A-14B1-40AC-B82E-D9057400E7EE}.debug|x64.Build.0 = debug|x64
|
||||
{B226530A-14B1-40AC-B82E-D9057400E7EE}.release|x64.ActiveCfg = release|x64
|
||||
{B226530A-14B1-40AC-B82E-D9057400E7EE}.release|x64.Build.0 = release|x64
|
||||
{9FA45E25-DAEB-4C2D-806C-7908A180195D}.debug|x64.ActiveCfg = debug|x64
|
||||
{9FA45E25-DAEB-4C2D-806C-7908A180195D}.debug|x64.Build.0 = debug|x64
|
||||
{9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.ActiveCfg = release|x64
|
||||
{9FA45E25-DAEB-4C2D-806C-7908A180195D}.release|x64.Build.0 = release|x64
|
||||
{360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.ActiveCfg = debug|x64
|
||||
{360E54B1-0B92-4BCA-8111-4BF384292621}.debug|x64.Build.0 = debug|x64
|
||||
{360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.ActiveCfg = release|x64
|
||||
{360E54B1-0B92-4BCA-8111-4BF384292621}.release|x64.Build.0 = release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -315,6 +429,20 @@ Global
|
|||
{991B8FA7-F75E-4D8A-A0BD-636FE68B6AF4} = {2104BCF9-035E-45AA-B744-68A5B8FEFF13}
|
||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
|
||||
{03550856-D63F-4069-87E1-8BF2F129DBE3} = {1997E4B6-FE49-4358-ADF1-CDDB5739508E}
|
||||
{17652C16-00A0-40D4-A227-697E595DE053} = {9A711E36-8A78-4CE6-A34D-F681AF89A919}
|
||||
{9E1A2FAF-696A-4CA7-8C2E-F6B80107A143} = {17652C16-00A0-40D4-A227-697E595DE053}
|
||||
{770B65D6-5307-478C-A9EB-3E4A64B67225} = {63D4BB7A-C404-4A35-A302-20034DD8BA77}
|
||||
{848FE945-4F37-4B5B-98C8-F22CA3AA7184} = {17652C16-00A0-40D4-A227-697E595DE053}
|
||||
{D3722A82-0A54-4172-A0C1-1EA6500E9F1E} = {770B65D6-5307-478C-A9EB-3E4A64B67225}
|
||||
{09E02C0A-6A6C-408A-8136-C787FDC58A5F} = {770B65D6-5307-478C-A9EB-3E4A64B67225}
|
||||
{C95E342A-9622-4351-8177-CDA43A52E7B2} = {DBE32379-8D5A-4454-A1B6-ACC407881898}
|
||||
{45ABB14F-86B9-40BE-9C0F-213653CE6A93} = {4BF590C3-1032-4DD2-BF87-BB9E5781977C}
|
||||
{1AA10217-07BF-490B-A688-1D1D6A267D52} = {DF15E9D4-976B-4E1D-B68F-9B67F93654BF}
|
||||
{78821DCF-DCFE-45B7-A9DD-3543BDF1FB9E} = {1AA10217-07BF-490B-A688-1D1D6A267D52}
|
||||
{AD02B952-0D75-47FE-8FF7-18B3E081E2C1} = {1AA10217-07BF-490B-A688-1D1D6A267D52}
|
||||
{9A0232BB-B06B-47EE-A096-E7B475956437} = {DF15E9D4-976B-4E1D-B68F-9B67F93654BF}
|
||||
{824DF7C7-18B5-48DE-99D7-AD6B612D6204} = {9A0232BB-B06B-47EE-A096-E7B475956437}
|
||||
{CA2D9C24-F90A-48ED-8ABC-F296674EA2B7} = {9A0232BB-B06B-47EE-A096-E7B475956437}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {1444BEC7-11CE-4CA6-B77C-5F98AC9BFAEB}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ set(SourceFiles
|
|||
"code/UnloadDll.c"
|
||||
"../include/components/spinlock/header/Spinlock.h"
|
||||
"../include/platform/kernel/header/Environment.h"
|
||||
"../include/platform/kernel/header/Mem.h"
|
||||
"../include/platform/kernel/header/PlatformMem.h"
|
||||
"header/Logging.h"
|
||||
"header/pch.h"
|
||||
"header/UnloadDll.h"
|
||||
|
|
|
|||
|
|
@ -11,12 +11,33 @@
|
|||
*/
|
||||
#include "pch.h"
|
||||
|
||||
#if ActivateHyperEvadeProject != TRUE
|
||||
|
||||
/**
|
||||
* @brief Handle The triggered hook on KiSystemCall64 system call handler
|
||||
* when the Transparency mode is disabled
|
||||
*
|
||||
* @param Regs The virtual processor's state of registers
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TransparentHandleSystemCallHook(GUEST_REGS * Regs)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Regs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function to handle returns from the syscall
|
||||
* when the Transparency mode is disabled
|
||||
*
|
||||
* @param Regs The virtual processor's state of registers
|
||||
* @param ProcessId The process id of the thread
|
||||
* @param ThreadId The thread id of the thread
|
||||
* @param Context The context of the caller
|
||||
* @param Params The (optional) parameters of the caller
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
|
||||
UINT32 ProcessId,
|
||||
|
|
@ -31,7 +52,7 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
|
|||
UNREFERENCED_PARAMETER(Params);
|
||||
}
|
||||
|
||||
#if DISABLE_HYPERDBG_HYPEREVADE == FALSE
|
||||
#else // ActivateHyperEvadeProject != TRUE
|
||||
|
||||
/**
|
||||
* @brief Handle The triggered hook on KiSystemCall64 system call handler
|
||||
|
|
@ -255,7 +276,7 @@ TransparentHandleNtQuerySystemInformationSyscall(GUEST_REGS * Regs)
|
|||
*
|
||||
* @details Returns an allocated tagged memory pointer which needs to be freed with PlatformMemFreePool()
|
||||
*
|
||||
* @param virtPtr A pointer to a guest virutal memory address, containing a OBJECT_ATTRIBUTES structure
|
||||
* @param virtPtr A pointer to a guest virtual memory address, containing a OBJECT_ATTRIBUTES structure
|
||||
* @return PVOID Pointer to an allocated tagged memory pool, which needs to be freed with PlatformMemFreePool()
|
||||
*/
|
||||
PVOID
|
||||
|
|
@ -690,7 +711,7 @@ TransparentHandleNtQueryValueKeySyscall(GUEST_REGS * Regs)
|
|||
&ContextParams);
|
||||
|
||||
//
|
||||
// Clean-up and return to guest exection
|
||||
// Clean-up and return to guest execution
|
||||
//
|
||||
PlatformMemFreePool(NameBuf);
|
||||
return;
|
||||
|
|
@ -805,7 +826,7 @@ TransparentHandleNtEnumerateKeySyscall(GUEST_REGS * Regs)
|
|||
* it is possible to still detect that some tampering was done from the user space
|
||||
*
|
||||
* @param Ptr The pointer to a valid read/writable SYSTEM_MODULE_INFORMATION memory buffer
|
||||
* @param VirualAddress A pointer to a user-mode virual address
|
||||
* @param VirtualAddress A pointer to a user-mode virtual address
|
||||
* @param BufferSize Size of the user-mode buffer
|
||||
*
|
||||
* @return BOOLEAN
|
||||
|
|
@ -822,11 +843,11 @@ TransparentHandleModuleInformationQuery(PVOID Ptr, UINT64 VirtualAddress, UINT32
|
|||
//
|
||||
for (UINT16 i = 0; i < StructBuf->Count; i++)
|
||||
{
|
||||
PCHAR path = (PCHAR)ModuleList[i].FullPathName;
|
||||
PCHAR Path = (PCHAR)ModuleList[i].FullPathName;
|
||||
|
||||
for (UINT16 j = 0; j < (sizeof(HV_DRIVER) / sizeof(HV_DRIVER[0])); j++)
|
||||
{
|
||||
if (strstr(path, HV_DRIVER[j]))
|
||||
if (strstr(Path, HV_DRIVER[j]))
|
||||
{
|
||||
//
|
||||
// If a module file name matches, remove the entry from the list by shifting it forward by one entry
|
||||
|
|
@ -934,9 +955,9 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
|
|||
//
|
||||
// Loop through the known list of identifiable hypervisor related processes
|
||||
//
|
||||
for (UINT16 i = 0; i < (sizeof(HV_Processes) / sizeof(HV_Processes[0])); i++)
|
||||
for (UINT16 i = 0; i < (sizeof(HV_PROCESSES) / sizeof(HV_PROCESSES[0])); i++)
|
||||
{
|
||||
if (!_wcsnicmp(ImageName, HV_Processes[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
|
||||
if (!_wcsnicmp(ImageName, HV_PROCESSES[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
|
||||
{
|
||||
//
|
||||
// If the name matches, bypass it by increasing the previous entries .nextEntryOffset value
|
||||
|
|
@ -987,7 +1008,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
|
|||
}
|
||||
|
||||
//
|
||||
// If the current entry didnt match any process names, move forward
|
||||
// If the current entry did not match any process names, move forward
|
||||
//
|
||||
if (!MatchFound)
|
||||
{
|
||||
|
|
@ -1037,7 +1058,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
|
|||
/**
|
||||
* @brief Handle the request for SystemFirmwareTableInformation
|
||||
*
|
||||
* @param ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
|
||||
* @param Ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
|
||||
* @param BufMaxSize The size of the allocated user-mode buffer
|
||||
* @param BufSizePtr A pointer to a ULONG field containing the size of the written data
|
||||
*
|
||||
|
|
@ -1063,7 +1084,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
|
|||
if (BufSize > BufMaxSize)
|
||||
{
|
||||
//
|
||||
// NOTE: might need zeroing the memory if the kernel did infact write to the pointer
|
||||
// NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1146,9 +1167,9 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
|
|||
//
|
||||
|
||||
ULONG MatchedStringLen = (ULONG)strlen(HV_FIRM_NAMES[i]);
|
||||
ULONG oldLength = StructBuf->TableBufferLength;
|
||||
ULONG OldLength = StructBuf->TableBufferLength;
|
||||
|
||||
ULONG NewStringSize = oldLength - MatchedStringLen + NewSubstringSize;
|
||||
ULONG NewStringSize = OldLength - MatchedStringLen + NewSubstringSize;
|
||||
|
||||
//
|
||||
// Check if the buffer size allows the modification, in case of expansion
|
||||
|
|
@ -1165,7 +1186,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
|
|||
//
|
||||
// Update the required buffer size for the next call
|
||||
//
|
||||
BufSize = (BufSize - oldLength) + NewStringSize;
|
||||
BufSize = (BufSize - OldLength) + NewStringSize;
|
||||
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG));
|
||||
|
||||
//
|
||||
|
|
@ -1186,7 +1207,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
|
|||
// Move the data after the matched string forward
|
||||
// and replace the identified hypervisor string with the genuine one
|
||||
//
|
||||
memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, oldLength - MatchedStringLen - MatchOffset);
|
||||
memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, OldLength - MatchedStringLen - MatchOffset);
|
||||
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, NewSubstringSize);
|
||||
|
||||
StructBuf->TableBufferLength = NewStringSize;
|
||||
|
|
@ -1230,8 +1251,8 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
|
|||
UINT64
|
||||
TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params, ULONG DataOffset, ULONG DataLenOffset)
|
||||
{
|
||||
PVOID Buf = NULL;
|
||||
BOOL PoolAlloc = FALSE;
|
||||
PVOID Buf = NULL;
|
||||
BOOLEAN PoolAlloc = FALSE;
|
||||
|
||||
//
|
||||
// Check that the user provided pointers are safe to read from
|
||||
|
|
@ -1253,7 +1274,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
|
|||
if (BufSize > Params->OptionalParam3 || BufSize == 0)
|
||||
{
|
||||
//
|
||||
// NOTE: might need zeroing the memory if the kernel did infact write to the pointer
|
||||
// NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
|
||||
//
|
||||
|
||||
return 0;
|
||||
|
|
@ -1313,7 +1334,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
|
|||
//
|
||||
// SPOOFS PCI device ID's(in the registry), This might be implemented in other ways that are not part of this implementation
|
||||
//
|
||||
WORD Idx = TRANSPARENT_GENUINE_VENDOR_STRING_INDEX % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
|
||||
WORD Idx = g_TransparentGenuineVendorStringIndex % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
|
||||
NewVendorString = TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[Idx];
|
||||
}
|
||||
|
||||
|
|
@ -1329,23 +1350,23 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
|
|||
//
|
||||
// Obtain the replacement vendor name string, randomized when the transparency mode was enabled
|
||||
//
|
||||
NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[TRANSPARENT_GENUINE_VENDOR_STRING_INDEX];
|
||||
NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[g_TransparentGenuineVendorStringIndex];
|
||||
}
|
||||
|
||||
//
|
||||
// Obtain the lengths of all the strings and substring
|
||||
//
|
||||
ULONG tempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
|
||||
ULONG TempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
|
||||
|
||||
ULONG MatchedStringLen = (ULONG)wcslen(HV_REGKEYS[i]) * sizeof(WCHAR);
|
||||
ULONG oldLength = *((PBYTE)Buf + DataLenOffset);
|
||||
ULONG OldLength = *((PBYTE)Buf + DataLenOffset);
|
||||
|
||||
ULONG NewStringSize = oldLength - MatchedStringLen + tempSize;
|
||||
ULONG NewStringSize = OldLength - MatchedStringLen + TempSize;
|
||||
|
||||
//
|
||||
// Check if the buffer size allows the modification, in case of expansion
|
||||
//
|
||||
if (BufSize - MatchedStringLen + tempSize > Params->OptionalParam3)
|
||||
if (BufSize - MatchedStringLen + TempSize > Params->OptionalParam3)
|
||||
{
|
||||
//
|
||||
// If adding the new string exceeds the user allocated size,
|
||||
|
|
@ -1357,7 +1378,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
|
|||
//
|
||||
// Update the required buffer size for the next call
|
||||
//
|
||||
BufSize = (tempSize - MatchedStringLen) + oldLength;
|
||||
BufSize = (TempSize - MatchedStringLen) + OldLength;
|
||||
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG));
|
||||
|
||||
//
|
||||
|
|
@ -1378,15 +1399,15 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
|
|||
//
|
||||
// Move the data after the matched string forward
|
||||
//
|
||||
memmove((PVOID)(StringBuf + MatchOffset + (tempSize / sizeof(WCHAR))), (PVOID)MatchEnd, oldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
|
||||
memmove((PVOID)(StringBuf + MatchOffset + (TempSize / sizeof(WCHAR))), (PVOID)MatchEnd, OldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
|
||||
|
||||
//
|
||||
// Replace the identified hypervisor string with the genuine one, if needed
|
||||
//
|
||||
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, tempSize);
|
||||
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, TempSize);
|
||||
|
||||
*(PULONG)((PBYTE)Buf + DataLenOffset) = NewStringSize;
|
||||
BufSize = BufSize - MatchedStringLen + tempSize;
|
||||
BufSize = BufSize - MatchedStringLen + TempSize;
|
||||
|
||||
//
|
||||
// Write the changes back to the user buffers
|
||||
|
|
@ -1519,7 +1540,7 @@ TransparentCallbackHandleAfterNtQueryValueKeySyscall(SYSCALL_CALLBACK_CONTEXT_PA
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Callback function to handle the returns from the NtQueryValueKey syscall
|
||||
* @brief Callback function to handle the returns from the NtEnumerateKey syscall
|
||||
*
|
||||
* @param Params The set transparent callback params that contain:
|
||||
in OptionalParam1 the KEY_VALUE_INFORMATION_CLASS enum value
|
||||
|
|
@ -1949,4 +1970,4 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
|
|||
Params->OptionalParam4);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // ActivateHyperEvadeProject != TRUE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
/**
|
||||
* @file Transparency.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author jtaw5649
|
||||
* @brief Try to hide the debugger from anti-debugging and anti-hypervisor methods
|
||||
* @details
|
||||
* @version 0.1
|
||||
|
|
@ -14,8 +15,8 @@
|
|||
/**
|
||||
* @brief Hide debugger on transparent-mode (activate transparent-mode)
|
||||
*
|
||||
* @param HyperevadeCallbacks
|
||||
* @param TransparentModeRequest
|
||||
* @param HyperevadeCallbacks Pointer to the HyperEvade callbacks structure
|
||||
* @param TransparentModeRequest Pointer to the transparent debugger mode request
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
|
|
@ -23,6 +24,19 @@ BOOLEAN
|
|||
TransparentHideDebugger(HYPEREVADE_CALLBACKS * HyperevadeCallbacks,
|
||||
DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
|
||||
{
|
||||
UINT32 EvadeMask = TransparentModeRequest->EvadeMask;
|
||||
|
||||
if (EvadeMask == 0)
|
||||
{
|
||||
EvadeMask = TRANSPARENT_EVADE_MASK_DEFAULT;
|
||||
}
|
||||
|
||||
if ((EvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
|
||||
{
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check if any of the required callbacks are NULL
|
||||
//
|
||||
|
|
@ -54,18 +68,20 @@ TransparentHideDebugger(HYPEREVADE_CALLBACKS * Hyperevade
|
|||
RtlCopyBytes(&g_SystemCallNumbersInformation,
|
||||
&TransparentModeRequest->SystemCallNumbersInformation,
|
||||
sizeof(SYSTEM_CALL_NUMBERS_INFORMATION));
|
||||
#if DISABLE_HYPERDBG_HYPEREVADE == FALSE
|
||||
#if ActivateHyperEvadeProject == TRUE
|
||||
//
|
||||
// Choose a random genuine vendor string to replace hypervisor vendor data
|
||||
//
|
||||
TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = TransparentGetRand() %
|
||||
(sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
|
||||
g_TransparentGenuineVendorStringIndex = TransparentGetRand() %
|
||||
(sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
|
||||
#endif
|
||||
|
||||
//
|
||||
// Enable the transparent mode
|
||||
//
|
||||
g_TransparentMode = TRUE;
|
||||
g_TransparentEvadeMask = EvadeMask;
|
||||
TransparentModeRequest->EvadeMask = EvadeMask;
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
|
||||
|
||||
//
|
||||
|
|
@ -93,7 +109,8 @@ TransparentUnhideDebugger()
|
|||
//
|
||||
// Disable the transparent-mode
|
||||
//
|
||||
g_TransparentMode = FALSE;
|
||||
g_TransparentMode = FALSE;
|
||||
g_TransparentEvadeMask = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -115,7 +132,7 @@ TransparentGetRand()
|
|||
UINT64 Tsc;
|
||||
UINT32 Rand;
|
||||
|
||||
Tsc = __rdtsc();
|
||||
Tsc = CpuReadTsc();
|
||||
Rand = Tsc & 0xffff;
|
||||
|
||||
return Rand;
|
||||
|
|
@ -125,7 +142,7 @@ TransparentGetRand()
|
|||
* @brief Add name or process id of the target process to the list
|
||||
* of processes that HyperDbg should apply transparent-mode on them
|
||||
*
|
||||
* @param Measurements
|
||||
* @param Measurements Pointer to the debugger hide and transparent mode request structure
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
|
|
@ -189,8 +206,8 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
|
|||
//
|
||||
// Move the process name string to the end of the buffer
|
||||
//
|
||||
RtlCopyBytes((void *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
|
||||
(const void *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
|
||||
RtlCopyBytes((VOID *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
|
||||
(CONST VOID *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
|
||||
Measurements->LengthOfProcessName);
|
||||
|
||||
//
|
||||
|
|
@ -599,7 +616,7 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
|
|||
// //
|
||||
// // Save the current time
|
||||
// //
|
||||
// CurrrentTime = __rdtscp(&Aux);
|
||||
// CurrrentTime = CpuReadTscp(&Aux);
|
||||
//
|
||||
// //
|
||||
// // Save time of vm-exit on each logical processor separately
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* @file UnloadDll.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Unloading DLL in the target Windows
|
||||
*
|
||||
* @details
|
||||
* @version 0.4
|
||||
* @date 2023-07-06
|
||||
*
|
||||
|
|
@ -18,6 +18,12 @@
|
|||
// other module remains loaded in the memory.
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief Routine called on DLL initialization
|
||||
*
|
||||
* @param RegistryPath The registry path of the driver
|
||||
* @return NTSTATUS
|
||||
*/
|
||||
NTSTATUS
|
||||
DllInitialize(
|
||||
_In_ PUNICODE_STRING RegistryPath)
|
||||
|
|
@ -27,8 +33,13 @@ DllInitialize(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Routine called on DLL unload
|
||||
*
|
||||
* @return NTSTATUS
|
||||
*/
|
||||
NTSTATUS
|
||||
DllUnload(void)
|
||||
DllUnload(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* @file VmxFootprints.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author jtaw5649
|
||||
* @brief Try to hide VMX methods from anti-debugging and anti-hypervisor
|
||||
* @details
|
||||
* @version 0.14
|
||||
|
|
@ -22,6 +23,11 @@
|
|||
VOID
|
||||
TransparentCheckAndModifyCpuid(PGUEST_REGS Regs, INT32 CpuInfo[])
|
||||
{
|
||||
if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_CPUID) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Regs->rax == CPUID_PROCESSOR_AND_PROCESSOR_FEATURE_IDENTIFIERS)
|
||||
{
|
||||
//
|
||||
|
|
@ -50,6 +56,14 @@ TransparentCheckAndModifyCpuid(PGUEST_REGS Regs, INT32 CpuInfo[])
|
|||
BOOLEAN
|
||||
TransparentCheckAndModifyMsrRead(PGUEST_REGS Regs, UINT32 TargetMsr)
|
||||
{
|
||||
if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_MSR) == 0)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Regs);
|
||||
UNREFERENCED_PARAMETER(TargetMsr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// The MSR range between 40000000H and 400000F0H is reserved and usually used by hypervisors
|
||||
// when the guest operating system is Windows to indicate the OS identifier
|
||||
|
|
@ -92,6 +106,14 @@ TransparentCheckAndModifyMsrRead(PGUEST_REGS Regs, UINT32 TargetMsr)
|
|||
BOOLEAN
|
||||
TransparentCheckAndModifyMsrWrite(PGUEST_REGS Regs, UINT32 TargetMsr)
|
||||
{
|
||||
if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_MSR) == 0)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(Regs);
|
||||
UNREFERENCED_PARAMETER(TargetMsr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// if (TargetMsr >= RESERVED_MSR_RANGE_LOW && TargetMsr <= RESERVED_MSR_RANGE_HI)
|
||||
// {
|
||||
// //
|
||||
|
|
@ -130,6 +152,11 @@ TransparentCheckAndModifyMsrWrite(PGUEST_REGS Regs, UINT32 TargetMsr)
|
|||
VOID
|
||||
TransparentCheckAndTrapFlagAfterVmexit()
|
||||
{
|
||||
if ((g_TransparentEvadeMask & TRANSPARENT_EVADE_MASK_TRAP_FLAG) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// If RIP is incremented, then we emulate an instruction, and then
|
||||
// we need to handle the trap flag if it is set in a guest
|
||||
|
|
|
|||
|
|
@ -81,17 +81,17 @@ typedef struct _SYSTEM_PROCESS_INFORMATION
|
|||
* @brief SSDT structure
|
||||
*
|
||||
*/
|
||||
typedef struct _SSDTStruct
|
||||
typedef struct _SSDT_STRUCT
|
||||
{
|
||||
LONG * pServiceTable;
|
||||
PVOID pCounterTable;
|
||||
LONG * ServiceTable;
|
||||
PVOID CounterTable;
|
||||
#ifdef _WIN64
|
||||
UINT64 NumberOfServices;
|
||||
#else
|
||||
ULONG NumberOfServices;
|
||||
#endif
|
||||
PCHAR pArgumentTable;
|
||||
} SSDTStruct, *PSSDTStruct;
|
||||
PCHAR ArgumentTable;
|
||||
} SSDT_STRUCT, *PSSDT_STRUCT;
|
||||
|
||||
/**
|
||||
* @brief Module entry
|
||||
|
|
@ -128,7 +128,7 @@ typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION)(
|
|||
IN ULONG SystemInformationLength,
|
||||
OUT PULONG ReturnLength OPTIONAL);
|
||||
|
||||
NTSTATUS(*NtCreateFileOrig)
|
||||
NTSTATUS(*g_NtCreateFileOrig)
|
||||
(
|
||||
PHANDLE FileHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
|
|
@ -150,7 +150,7 @@ NTSTATUS(*NtCreateFileOrig)
|
|||
* @brief A variable holding the randomly chosen index for the genuine vendor list.
|
||||
* This is used for transparent vendor spoofing
|
||||
*/
|
||||
static WORD TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = 0;
|
||||
static WORD g_TransparentGenuineVendorStringIndex = 0;
|
||||
|
||||
/**
|
||||
* @brief System call numbers information
|
||||
|
|
@ -161,7 +161,7 @@ SYSTEM_CALL_NUMBERS_INFORMATION g_SystemCallNumbersInformation;
|
|||
// Constants //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
#if DISABLE_HYPERDBG_HYPEREVADE == FALSE
|
||||
#if ActivateHyperEvadeProject == TRUE
|
||||
|
||||
/**
|
||||
* @brief A list of windows processes, for which to ignore systemcall requests
|
||||
|
|
@ -241,7 +241,7 @@ static const PWCHAR TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[] = {
|
|||
* @brief A list of common Hypervisor specific process executables
|
||||
*
|
||||
*/
|
||||
static const PWCH HV_Processes[] = {
|
||||
static const PWCH HV_PROCESSES[] = {
|
||||
L"hyperdbg-cli.exe",
|
||||
L"vboxservice.exe",
|
||||
L"vmsrvc.exe",
|
||||
|
|
@ -362,7 +362,7 @@ static const PWCH HV_FILES[] = {
|
|||
// HyperDbg Files
|
||||
//
|
||||
L"hyperhv",
|
||||
L"hyperkd"
|
||||
L"hyperkd",
|
||||
L"hyperlog",
|
||||
L"libhyperdbg",
|
||||
|
||||
|
|
@ -559,11 +559,12 @@ static const PWCH HV_REGKEYS[] = {
|
|||
|
||||
};
|
||||
|
||||
//
|
||||
// @brief A list of registry keys which might contain hypervisor vendor information in their data
|
||||
//
|
||||
// NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
|
||||
//
|
||||
/**
|
||||
* @brief A list of registry keys which might contain hypervisor vendor information in their data
|
||||
*
|
||||
* @details NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
|
||||
*
|
||||
*/
|
||||
static const PWCH TRANSPARENT_DETECTABLE_REGISTRY_KEYS[] = {
|
||||
L"AcpiData",
|
||||
L"SMBiosData",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* @file Transparency.h
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author jtaw5649
|
||||
* @brief hide the debugger from anti-debugging and anti-hypervisor methods (headers)
|
||||
* @details
|
||||
* @version 0.1
|
||||
|
|
@ -64,6 +65,12 @@ typedef struct _TRANSPARENCY_PROCESS
|
|||
*/
|
||||
BOOLEAN g_TransparentMode;
|
||||
|
||||
/**
|
||||
* @brief The enabled transparent-mode feature mask
|
||||
*
|
||||
*/
|
||||
UINT32 g_TransparentEvadeMask;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Functions //
|
||||
//////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* @file VmxFootprint.h
|
||||
* @file VmxFootprints.h
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Hide the debugger from VMX-footrpints of anti-debugging and anti-hypervisor methods (headers)
|
||||
* @brief Hide the debugger from VMX-footprints of anti-debugging and anti-hypervisor methods (headers)
|
||||
* @details
|
||||
* @version 0.14
|
||||
* @date 2024-08-06
|
||||
|
|
|
|||
|
|
@ -19,16 +19,9 @@
|
|||
//
|
||||
// Environment headers
|
||||
//
|
||||
#include "platform/kernel/header/Environment.h"
|
||||
#include "platform/general/header/Environment.h"
|
||||
|
||||
#ifdef ENV_WINDOWS
|
||||
|
||||
//
|
||||
// The DLL is flagged by antivirus software, since it contains anti-debugging and anti-hypervisor methods
|
||||
// as well as different anti-debugging strings
|
||||
// For now, we disable the HyperDbg Hyperevade module
|
||||
//
|
||||
# define DISABLE_HYPERDBG_HYPEREVADE TRUE
|
||||
#ifdef HYPERDBG_ENV_WINDOWS
|
||||
|
||||
//
|
||||
// Windows defined functions
|
||||
|
|
@ -37,7 +30,7 @@
|
|||
# include <ntstrsafe.h>
|
||||
# include <Windef.h>
|
||||
|
||||
#endif // ENV_WINDOWS
|
||||
#endif // HYPERDBG_ENV_WINDOWS
|
||||
|
||||
//
|
||||
// Scope definitions
|
||||
|
|
@ -68,13 +61,14 @@
|
|||
//
|
||||
// Hyperlog headers
|
||||
//
|
||||
#include "components/interface/HyperLogCallback.h"
|
||||
#include "components/callback/header/HyperLogCallback.h"
|
||||
#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
|
||||
|
||||
//
|
||||
// Platform independent headers
|
||||
//
|
||||
#include "platform/kernel/header/Mem.h"
|
||||
#include "platform/kernel/header/PlatformMem.h"
|
||||
#include "platform/kernel/header/PlatformIntrinsics.h"
|
||||
|
||||
//
|
||||
// Hyperevade Callbacks
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
@ -100,29 +103,42 @@
|
|||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\hyperhv\code\components\registers\DebugRegisters.c" />
|
||||
<ClCompile Include="..\include\components\interface\HyperLogCallback.c" />
|
||||
<ClCompile Include="..\include\components\callback\code\HyperLogCallback.c" />
|
||||
<ClCompile Include="..\include\components\optimizations\code\AvlTree.c" />
|
||||
<ClCompile Include="..\include\components\optimizations\code\BinarySearch.c" />
|
||||
<ClCompile Include="..\include\components\optimizations\code\InsertionSort.c" />
|
||||
<ClCompile Include="..\include\components\optimizations\code\OptimizationsExamples.c" />
|
||||
<ClCompile Include="..\include\components\spinlock\code\Spinlock.c" />
|
||||
<ClCompile Include="..\include\platform\kernel\code\Mem.c" />
|
||||
<ClCompile Include="..\include\platform\kernel\code\PlatformIntrinsics.c" />
|
||||
<ClCompile Include="..\include\platform\kernel\code\PlatformMem.c" />
|
||||
<ClCompile Include="code\SyscallFootprints.c" />
|
||||
<ClCompile Include="code\Transparency.c" />
|
||||
<ClCompile Include="code\UnloadDll.c" />
|
||||
<ClCompile Include="code\VmxFootprints.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\components\interface\HyperLogCallback.h" />
|
||||
<ClInclude Include="..\include\platform\kernel\header\Environment.h" />
|
||||
<ClInclude Include="..\include\platform\kernel\header\Mem.h" />
|
||||
<ClInclude Include="..\include\components\callback\header\HyperLogCallback.h" />
|
||||
<ClInclude Include="..\include\platform\kernel\header\PlatformIntrinsics.h" />
|
||||
<ClInclude Include="..\include\platform\kernel\header\PlatformMem.h" />
|
||||
<ClInclude Include="header\SyscallFootprints.h" />
|
||||
<ClInclude Include="header\Transparency.h" />
|
||||
<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>
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
<Filter Include="code\components">
|
||||
<UniqueIdentifier>{890885f8-de8f-41df-9202-3ec320d7d816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\components\registers">
|
||||
<UniqueIdentifier>{228a6a7a-4085-4871-a29b-15ca5576623d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\components\spinlock">
|
||||
<UniqueIdentifier>{a66d71db-112c-4826-8181-ba265d339149}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\components\optimizations">
|
||||
<UniqueIdentifier>{da60b9fe-3816-4f3c-a6a9-21accd463156}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="code\interface">
|
||||
<UniqueIdentifier>{895edb89-17e8-4a1e-a648-b0ea360e98f8}</UniqueIdentifier>
|
||||
<Filter Include="code\components\callback">
|
||||
<UniqueIdentifier>{0e801893-09df-4299-a572-6e63049d4f9f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\interface">
|
||||
<UniqueIdentifier>{7c6fe4d9-4baf-4fd2-93e0-ee395cbc2ee9}</UniqueIdentifier>
|
||||
<Filter Include="header\components">
|
||||
<UniqueIdentifier>{78b7809e-ea12-450d-af96-8e658087628d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="header\components\callback">
|
||||
<UniqueIdentifier>{28025c67-f68b-437b-bcda-d23c9a752d42}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -45,12 +45,9 @@
|
|||
<ClCompile Include="code\UnloadDll.c">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\platform\kernel\code\Mem.c">
|
||||
<ClCompile Include="..\include\platform\kernel\code\PlatformMem.c">
|
||||
<Filter>code\platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\hyperhv\code\components\registers\DebugRegisters.c">
|
||||
<Filter>code\components\registers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\components\spinlock\code\Spinlock.c">
|
||||
<Filter>code\components\spinlock</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -66,15 +63,18 @@
|
|||
<ClCompile Include="..\include\components\optimizations\code\OptimizationsExamples.c">
|
||||
<Filter>code\components\optimizations</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\components\interface\HyperLogCallback.c">
|
||||
<Filter>code\interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\SyscallFootprints.c">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="code\VmxFootprints.c">
|
||||
<Filter>code</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\platform\kernel\code\PlatformIntrinsics.c">
|
||||
<Filter>code\platform</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\include\components\callback\code\HyperLogCallback.c">
|
||||
<Filter>code\components\callback</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="header\Transparency.h">
|
||||
|
|
@ -83,20 +83,23 @@
|
|||
<ClInclude Include="header\pch.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\platform\kernel\header\Environment.h">
|
||||
<ClInclude Include="..\include\platform\kernel\header\PlatformMem.h">
|
||||
<Filter>header\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\platform\kernel\header\Mem.h">
|
||||
<Filter>header\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\components\interface\HyperLogCallback.h">
|
||||
<Filter>header\interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\SyscallFootprints.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="header\VmxFootprints.h">
|
||||
<Filter>header</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\platform\kernel\header\PlatformIntrinsics.h">
|
||||
<Filter>header\platform</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\components\callback\header\HyperLogCallback.h">
|
||||
<Filter>header\components\callback</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
hyperdbg/hyperevade/packages.config
Normal file
6
hyperdbg/hyperevade/packages.config
Normal 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>
|
||||
|
|
@ -5,7 +5,7 @@ set(SourceFiles
|
|||
"../include/components/optimizations/code/InsertionSort.c"
|
||||
"../include/components/optimizations/code/OptimizationsExamples.c"
|
||||
"../include/components/spinlock/code/Spinlock.c"
|
||||
"../include/platform/kernel/code/Mem.c"
|
||||
"../include/platform/kernel/code/PlatformMem.c"
|
||||
"code/broadcast/Broadcast.c"
|
||||
"code/broadcast/DpcRoutines.c"
|
||||
"code/common/Bitwise.c"
|
||||
|
|
@ -102,7 +102,7 @@ set(SourceFiles
|
|||
"../include/components/spinlock/header/Spinlock.h"
|
||||
"../include/macros/MetaMacros.h"
|
||||
"../include/platform/kernel/header/Environment.h"
|
||||
"../include/platform/kernel/header/Mem.h"
|
||||
"../include/platform/kernel/header/PlatformMem.h"
|
||||
"header/assembly/InlineAsm.h"
|
||||
"header/broadcast/Broadcast.h"
|
||||
"header/broadcast/DpcRoutines.h"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ PUBLIC AsmVmexitHandler
|
|||
PUBLIC AsmVmxoffRestoreXmmRegs
|
||||
|
||||
EXTERN VmxVmexitHandler:PROC
|
||||
EXTERN VmxVmresume:PROC
|
||||
EXTERN VmxPerformVmresume:PROC
|
||||
EXTERN VmxReturnStackPointerForVmxoff:PROC
|
||||
EXTERN VmxReturnInstructionPointerForVmxoff:PROC
|
||||
|
||||
|
|
@ -138,7 +138,7 @@ RestoreState:
|
|||
|
||||
; ----------------------------------------------
|
||||
|
||||
jmp VmxVmresume
|
||||
jmp VmxPerformVmresume
|
||||
|
||||
AsmVmexitHandler ENDP
|
||||
|
||||
|
|
|
|||
|
|
@ -135,15 +135,10 @@ DpcRoutinePerformVirtualization(KDPC * Dpc, PVOID DeferredContext, PVOID SystemA
|
|||
//
|
||||
VmxPerformVirtualizationOnSpecificCore();
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -454,15 +449,10 @@ DpcRoutineEnableMovToCr3Exiting(KDPC * Dpc, PVOID DeferredContext, PVOID SystemA
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_CR3_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -485,15 +475,10 @@ DpcRoutineChangeToMbecSupportedEptp(KDPC * Dpc, PVOID DeferredContext, PVOID Sys
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_CHANGE_TO_MBEC_SUPPORTED_EPTP, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -516,15 +501,10 @@ DpcRoutineRestoreToNormalEptp(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArg
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_RESTORE_TO_NORMAL_EPTP, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -547,15 +527,10 @@ DpcRoutineEnableOrDisableMbec(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArg
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_OR_ENABLE_MBEC, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -578,15 +553,10 @@ DpcRoutineDisableMovToCr3Exiting(KDPC * Dpc, PVOID DeferredContext, PVOID System
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CR3_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -609,15 +579,10 @@ DpcRoutineEnableEferSyscallEvents(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_SYSCALL_HOOK_EFER, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -640,15 +605,10 @@ DpcRoutineDisableEferSyscallEvents(KDPC * Dpc, PVOID DeferredContext, PVOID Syst
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_SYSCALL_HOOK_EFER, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -671,15 +631,10 @@ DpcRoutineEnablePml(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, PV
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_DIRTY_LOGGING_MECHANISM, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -702,15 +657,10 @@ DpcRoutineDisablePml(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument1, P
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_DIRTY_LOGGING_MECHANISM, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -732,15 +682,10 @@ DpcRoutineChangeMsrBitmapReadOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_CHANGE_MSR_BITMAP_READ, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -763,15 +708,10 @@ DpcRoutineResetMsrBitmapReadOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_RESET_MSR_BITMAP_READ, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -793,15 +733,10 @@ DpcRoutineChangeMsrBitmapWriteOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_CHANGE_MSR_BITMAP_WRITE, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -824,15 +759,10 @@ DpcRoutineResetMsrBitmapWriteOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_RESET_MSR_BITMAP_WRITE, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -855,15 +785,10 @@ DpcRoutineEnableRdtscExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_RDTSC_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -886,15 +811,10 @@ DpcRoutineDisableRdtscExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID S
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_RDTSC_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -919,15 +839,10 @@ DpcRoutineDisableRdtscExitingForClearingTscEventsAllCores(KDPC * Dpc, PVOID Defe
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_RDTSC_EXITING_ONLY_FOR_TSC_EVENTS, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -951,15 +866,10 @@ DpcRoutineDisableMov2DrExitingForClearingDrEventsAllCores(KDPC * Dpc, PVOID Defe
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_HW_DR_EXITING_ONLY_FOR_DR_EVENTS, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -982,15 +892,10 @@ DpcRoutineDisableMov2CrExitingForClearingCrEventsAllCores(KDPC * Dpc, DEBUGGER_E
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CR_EXITING_ONLY_FOR_CR_EVENTS, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1013,15 +918,10 @@ DpcRoutineEnableRdpmcExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_RDPMC_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1044,15 +944,10 @@ DpcRoutineDisableRdpmcExitingAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID S
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_RDPMC_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1074,15 +969,10 @@ DpcRoutineSetExceptionBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1104,15 +994,10 @@ DpcRoutineUnsetExceptionBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1139,15 +1024,10 @@ DpcRoutineResetExceptionBitmapOnlyOnClearingExceptionEventsOnAllCores(KDPC * Dpc
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_RESET_EXCEPTION_BITMAP_ONLY_ON_CLEARING_EXCEPTION_EVENTS, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1170,15 +1050,10 @@ DpcRoutineEnableMovDebigRegisterExitingAllCores(KDPC * Dpc, PVOID DeferredContex
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_DEBUG_REGS_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1200,15 +1075,10 @@ DpcRoutineEnableMovControlRegisterExitingAllCores(KDPC * Dpc, DEBUGGER_EVENT_OPT
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_MOV_TO_CONTROL_REGS_EXITING, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1230,15 +1100,10 @@ DpcRoutineDisableMovControlRegisterExitingAllCores(KDPC * Dpc, DEBUGGER_EVENT_OP
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_CONTROL_REGS_EXITING, EventOptions->OptionalParam1, EventOptions->OptionalParam2, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1261,15 +1126,10 @@ DpcRoutineDisableMovDebigRegisterExitingAllCores(KDPC * Dpc, PVOID DeferredConte
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_MOV_TO_DEBUG_REGS_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1292,15 +1152,10 @@ DpcRoutineSetEnableExternalInterruptExitingOnAllCores(KDPC * Dpc, PVOID Deferred
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_ENABLE_EXTERNAL_INTERRUPT_EXITING, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1326,15 +1181,10 @@ DpcRoutineSetDisableExternalInterruptExitingOnlyOnClearingInterruptEventsOnAllCo
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_DISABLE_EXTERNAL_INTERRUPT_EXITING_ONLY_TO_CLEAR_INTERRUPT_COMMANDS, 0, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1356,15 +1206,10 @@ DpcRoutineChangeIoBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syst
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_CHANGE_IO_BITMAP, (UINT64)DeferredContext, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1387,15 +1232,10 @@ DpcRoutineResetIoBitmapOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_RESET_IO_BITMAP, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1418,15 +1258,10 @@ DpcRoutineEnableBreakpointOnExceptionBitmapOnAllCores(KDPC * Dpc, PVOID Deferred
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_BREAKPOINT, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1449,15 +1284,10 @@ DpcRoutineDisableBreakpointOnExceptionBitmapOnAllCores(KDPC * Dpc, PVOID Deferre
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_BREAKPOINT, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1480,15 +1310,10 @@ DpcRoutineEnableNmiVmexitOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sys
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_VM_EXIT_ON_NMIS, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1511,15 +1336,10 @@ DpcRoutineDisableNmiVmexitOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Sy
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_VM_EXIT_ON_NMIS, NULL64_ZERO, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1547,15 +1367,10 @@ DpcRoutineEnableDbAndBpExitingOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOI
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_SET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_DEBUG_BREAKPOINT, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1583,15 +1398,10 @@ DpcRoutineDisableDbAndBpExitingOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVO
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNSET_EXCEPTION_BITMAP, EXCEPTION_VECTOR_DEBUG_BREAKPOINT, 0, 0);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1614,15 +1424,10 @@ DpcRoutineRemoveHookAndInvalidateAllEntriesOnAllCores(KDPC * Dpc, PVOID Deferred
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNHOOK_ALL_PAGES, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1647,15 +1452,10 @@ DpcRoutineRemoveHookAndInvalidateSingleEntryOnAllCores(KDPC * Dpc, PVOID Deferre
|
|||
//
|
||||
AsmVmxVmcall(VMCALL_UNHOOK_SINGLE_PAGE, UnhookingDetail->PhysicalAddress, UnhookingDetail->OriginalEntry, NULL64_ZERO);
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1690,15 +1490,10 @@ DpcRoutineInvalidateEptOnAllCores(KDPC * Dpc, PVOID DeferredContext, PVOID Syste
|
|||
NULL64_ZERO);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1721,15 +1516,10 @@ DpcRoutineInitializeGuest(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgumen
|
|||
//
|
||||
AsmVmxSaveState();
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1755,13 +1545,8 @@ DpcRoutineTerminateGuest(KDPC * Dpc, PVOID DeferredContext, PVOID SystemArgument
|
|||
LogError("Err, there were an error terminating vmx");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Synchronize the end of this routine with the caller
|
||||
//
|
||||
// Wait for all DPCs to synchronize at this point
|
||||
//
|
||||
KeSignalCallDpcSynchronize(SystemArgument2);
|
||||
|
||||
//
|
||||
// Mark the DPC as being complete
|
||||
//
|
||||
KeSignalCallDpcDone(SystemArgument1);
|
||||
PlatformBroadcastSynchronizeEndOfRoutine(SystemArgument1, SystemArgument2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,35 +15,35 @@
|
|||
* @brief Check whether the bit is set or not
|
||||
*
|
||||
* @param BitNumber
|
||||
* @param addr
|
||||
* @return int
|
||||
* @param Addr
|
||||
* @return INT
|
||||
*/
|
||||
int
|
||||
TestBit(int BitNumber, unsigned long * addr)
|
||||
INT
|
||||
TestBit(INT BitNumber, ULONG * Addr)
|
||||
{
|
||||
return (BITMAP_ENTRY(BitNumber, addr) >> BITMAP_SHIFT(BitNumber)) & 1;
|
||||
return (BITMAP_ENTRY(BitNumber, Addr) >> BITMAP_SHIFT(BitNumber)) & 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief unset the bit
|
||||
*
|
||||
* @param BitNumber
|
||||
* @param addr
|
||||
* @param Addr
|
||||
*/
|
||||
void
|
||||
ClearBit(int BitNumber, unsigned long * addr)
|
||||
VOID
|
||||
ClearBit(INT BitNumber, ULONG * Addr)
|
||||
{
|
||||
BITMAP_ENTRY(BitNumber, addr) &= ~(1UL << BITMAP_SHIFT(BitNumber));
|
||||
BITMAP_ENTRY(BitNumber, Addr) &= ~(1UL << BITMAP_SHIFT(BitNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set the bit
|
||||
*
|
||||
* @param BitNumber
|
||||
* @param addr
|
||||
* @param Addr
|
||||
*/
|
||||
void
|
||||
SetBit(int BitNumber, unsigned long * addr)
|
||||
VOID
|
||||
SetBit(INT BitNumber, ULONG * Addr)
|
||||
{
|
||||
BITMAP_ENTRY(BitNumber, addr) |= (1UL << BITMAP_SHIFT(BitNumber));
|
||||
BITMAP_ENTRY(BitNumber, Addr) |= (1UL << BITMAP_SHIFT(BitNumber));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,30 +61,30 @@ CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess)
|
|||
/**
|
||||
* @brief Detects whether the string starts with another string
|
||||
*
|
||||
* @param const char * pre
|
||||
* @param const char * str
|
||||
* @param pre
|
||||
* @param str
|
||||
* @return BOOLEAN Returns true if it starts with and false if not strats with
|
||||
*/
|
||||
BOOLEAN
|
||||
CommonIsStringStartsWith(const char * pre, const char * str)
|
||||
CommonIsStringStartsWith(const CHAR * pre, const CHAR * str)
|
||||
{
|
||||
size_t lenpre = strlen(pre),
|
||||
lenstr = strlen(str);
|
||||
return lenstr < lenpre ? FALSE : memcmp(pre, str, lenpre) == 0;
|
||||
SIZE_T LenPre = strlen(pre),
|
||||
LenStr = strlen(str);
|
||||
return LenStr < LenPre ? FALSE : memcmp(pre, str, LenPre) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get cpuid results
|
||||
*
|
||||
* @param UINT32 Func
|
||||
* @param UINT32 SubFunc
|
||||
* @param int * CpuInfo
|
||||
* @param Func
|
||||
* @param SubFunc
|
||||
* @param CpuInfo
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, int * CpuInfo)
|
||||
CommonCpuidInstruction(UINT32 Func, UINT32 SubFunc, INT * CpuInfo)
|
||||
{
|
||||
__cpuidex(CpuInfo, Func, SubFunc);
|
||||
CpuCpuIdEx(CpuInfo, Func, SubFunc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -156,7 +156,7 @@ CommonWriteDebugInformation(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
|
||||
MemoryMapperReadMemorySafeOnTargetProcess(VCpu->LastVmexitRip, Instruction, MAXIMUM_INSTR_SIZE);
|
||||
|
||||
for (size_t i = 0; i < MAXIMUM_INSTR_SIZE; i++)
|
||||
for (SIZE_T i = 0; i < MAXIMUM_INSTR_SIZE; i++)
|
||||
{
|
||||
Log("%02X ", Instruction[i] & 0xffU);
|
||||
}
|
||||
|
|
@ -249,4 +249,4 @@ CommonIsXCr0Valid(XCR0 XCr0)
|
|||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file DebugRegisters.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Implementation of debug registers functions
|
||||
|
|
@ -77,7 +77,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
|
|||
//
|
||||
if (DebugRegNum == 0)
|
||||
{
|
||||
__writedr(0, TargetAddress);
|
||||
CpuWriteDr(0, TargetAddress);
|
||||
|
||||
Dr7.GlobalBreakpoint0 = 1;
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
|
|||
}
|
||||
else if (DebugRegNum == 1)
|
||||
{
|
||||
__writedr(1, TargetAddress);
|
||||
CpuWriteDr(1, TargetAddress);
|
||||
Dr7.GlobalBreakpoint1 = 1;
|
||||
|
||||
//
|
||||
|
|
@ -160,7 +160,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
|
|||
}
|
||||
else if (DebugRegNum == 2)
|
||||
{
|
||||
__writedr(2, TargetAddress);
|
||||
CpuWriteDr(2, TargetAddress);
|
||||
Dr7.GlobalBreakpoint2 = 1;
|
||||
|
||||
//
|
||||
|
|
@ -201,7 +201,7 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
|
|||
}
|
||||
else if (DebugRegNum == 3)
|
||||
{
|
||||
__writedr(3, TargetAddress);
|
||||
CpuWriteDr(3, TargetAddress);
|
||||
Dr7.GlobalBreakpoint3 = 1;
|
||||
|
||||
//
|
||||
|
|
@ -248,11 +248,11 @@ SetDebugRegisters(UINT32 DebugRegNum, DEBUG_REGISTER_TYPE ActionType, BOOLEAN Ap
|
|||
//
|
||||
if (ApplyToVmcs)
|
||||
{
|
||||
__vmx_vmwrite(VMCS_GUEST_DR7, Dr7.AsUInt);
|
||||
HvSetDebugReg7(Dr7.AsUInt);
|
||||
}
|
||||
else
|
||||
{
|
||||
__writedr(7, Dr7.AsUInt);
|
||||
CpuWriteDr(7, Dr7.AsUInt);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Perfom read I/O APIC
|
||||
* @brief Perform read I/O APIC
|
||||
*
|
||||
* @param IoApicBaseVa
|
||||
* @param Reg
|
||||
|
|
@ -45,7 +45,7 @@ IoApicRead(volatile IO_APIC_ENT * IoApicBaseVa, UINT32 Reg)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Perfom write to I/O APIC
|
||||
* @brief Perform write to I/O APIC
|
||||
*
|
||||
* @param IoApicBaseVa
|
||||
* @param Reg
|
||||
|
|
@ -79,18 +79,18 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
|
|||
{
|
||||
UINT32 Index = 0;
|
||||
UINT32 Max;
|
||||
UINT64 ll, lh;
|
||||
UINT64 Ll, Lh;
|
||||
|
||||
UINT64 ApicBasePa = IO_APIC_DEFAULT_BASE_ADDR;
|
||||
|
||||
ll = IoApicRead(g_IoApicBase, IO_VERS_REGISTER),
|
||||
Ll = IoApicRead(g_IoApicBase, IO_VERS_REGISTER),
|
||||
|
||||
Max = (ll >> 16) & 0xff;
|
||||
Max = (Ll >> 16) & 0xff;
|
||||
|
||||
// Log("IoApic @ %08x ID:%x (%x) Arb:%x\n",
|
||||
// ApicBasePa,
|
||||
// IoApicRead(g_IoApicBase, IO_ID_REGISTER) >> 24,
|
||||
// ll & 0xFF,
|
||||
// Ll & 0xFF,
|
||||
// IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER));
|
||||
|
||||
//
|
||||
|
|
@ -99,7 +99,7 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
|
|||
IoApicPackets->ApicBasePa = (UINT32)ApicBasePa;
|
||||
IoApicPackets->ApicBaseVa = (UINT64)g_IoApicBase;
|
||||
IoApicPackets->IoIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ID_REGISTER);
|
||||
IoApicPackets->IoLl = (UINT32)ll;
|
||||
IoApicPackets->IoLl = (UINT32)Ll;
|
||||
IoApicPackets->IoArbIdReg = (UINT32)IoApicRead(g_IoApicBase, IO_ARB_ID_REGISTER);
|
||||
|
||||
//
|
||||
|
|
@ -117,11 +117,11 @@ ApicDumpIoApic(IO_APIC_ENTRY_PACKETS * IoApicPackets)
|
|||
return;
|
||||
}
|
||||
|
||||
ll = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 0);
|
||||
lh = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 1);
|
||||
Ll = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 0);
|
||||
Lh = IoApicRead(g_IoApicBase, IO_REDIR_BASE + Index + 1);
|
||||
|
||||
IoApicPackets->LlLhData[Index] = ll;
|
||||
IoApicPackets->LlLhData[Index + 1] = lh;
|
||||
IoApicPackets->LlLhData[Index] = Ll;
|
||||
IoApicPackets->LlLhData[Index + 1] = Lh;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ XApicIcrWrite(UINT32 Low, UINT32 High)
|
|||
VOID
|
||||
X2ApicIcrWrite(UINT32 Low, UINT32 High)
|
||||
{
|
||||
__writemsr(X2_MSR_BASE + TO_X2(ICROffset), ((UINT64)High << 32) | Low);
|
||||
CpuWriteMsr(X2_MSR_BASE + TO_X2(ICROffset), ((UINT64)High << 32) | Low);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -161,7 +161,7 @@ X2ApicIcrWrite(UINT32 Low, UINT32 High)
|
|||
UINT64
|
||||
X2ApicRead(UINT32 Offset)
|
||||
{
|
||||
return __readmsr(X2_MSR_BASE + TO_X2(Offset));
|
||||
return CpuReadMsr(X2_MSR_BASE + TO_X2(Offset));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -369,7 +369,7 @@ ApicInitialize()
|
|||
PHYSICAL_ADDRESS PaApicBase;
|
||||
PHYSICAL_ADDRESS PaIoApicBase;
|
||||
|
||||
ApicBaseMSR = __readmsr(IA32_APIC_BASE);
|
||||
ApicBaseMSR = CpuReadMsr(IA32_APIC_BASE);
|
||||
|
||||
if (!(ApicBaseMSR & (1 << 11)))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ DirtyLoggingInitialize()
|
|||
// the 4 - KByte aligned physical address of the page - modification log.The page modification
|
||||
// log comprises 512 64 - bit entries
|
||||
//
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
if (g_GuestState[i].PmlBufferAddress == NULL)
|
||||
{
|
||||
|
|
@ -65,7 +65,7 @@ DirtyLoggingInitialize()
|
|||
//
|
||||
// Allocation failed
|
||||
//
|
||||
for (size_t j = 0; j < ProcessorsCount; j++)
|
||||
for (SIZE_T j = 0; j < ProcessorsCount; j++)
|
||||
{
|
||||
if (g_GuestState[j].PmlBufferAddress != NULL)
|
||||
{
|
||||
|
|
@ -119,12 +119,12 @@ DirtyLoggingEnable(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
|
||||
// LogInfo("PML Buffer Address = %llx", PmlPhysAddr);
|
||||
|
||||
__vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
|
||||
VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
|
||||
|
||||
//
|
||||
// Clear the PML index
|
||||
//
|
||||
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
|
||||
//
|
||||
// If the "enable PML" VM-execution control is 1 and bit 6 of EPT pointer (EPTP)
|
||||
|
|
@ -160,12 +160,12 @@ DirtyLoggingDisable(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Clear the address
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
|
||||
VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
|
||||
|
||||
//
|
||||
// Clear the PML index
|
||||
//
|
||||
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, 0x0);
|
||||
VmxVmwrite64(VMCS_GUEST_PML_INDEX, 0x0);
|
||||
|
||||
//
|
||||
// Disable PML Enable bit
|
||||
|
|
@ -196,7 +196,7 @@ DirtyLoggingUninitialize()
|
|||
//
|
||||
// Free the allocated pool buffers
|
||||
//
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
if (g_GuestState[i].PmlBufferAddress != NULL)
|
||||
{
|
||||
|
|
@ -218,7 +218,7 @@ DirtyLoggingHandlePageModificationLog(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// The guest-physical address of the access is written to the page-modification log
|
||||
//
|
||||
for (size_t i = 0; i < PML_ENTITY_NUM; i++)
|
||||
for (SIZE_T i = 0; i < PML_ENTITY_NUM; i++)
|
||||
{
|
||||
LogInfo("Address : %llx", VCpu->PmlBufferAddress[i]);
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ DirtyLoggingFlushPmlBuffer(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// reset PML index
|
||||
//
|
||||
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,22 +80,22 @@ EptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
|
|||
// Request pages to be allocated for converting 2MB to 4KB pages
|
||||
// Each core needs its own splitting page-tables
|
||||
//
|
||||
PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
|
||||
PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
|
||||
|
||||
//
|
||||
// Request pages to be allocated for paged hook details
|
||||
//
|
||||
PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
|
||||
PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
|
||||
|
||||
//
|
||||
// Request pages to be allocated for Trampoline of Executable hooked pages
|
||||
//
|
||||
PoolManagerRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
|
||||
PoolManagerCallbackRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
|
||||
|
||||
//
|
||||
// Request pages to be allocated for detour hooked pages details
|
||||
//
|
||||
PoolManagerRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
|
||||
PoolManagerCallbackRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -120,16 +120,16 @@ EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks(UINT32 Count)
|
|||
// Request pages to be allocated for converting 2MB to 4KB pages
|
||||
// Each core needs its own splitting page-tables
|
||||
//
|
||||
PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
|
||||
Count * ProcessorsCount,
|
||||
SPLIT_2MB_PAGING_TO_4KB_PAGE);
|
||||
PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
|
||||
Count * ProcessorsCount,
|
||||
SPLIT_2MB_PAGING_TO_4KB_PAGE);
|
||||
|
||||
//
|
||||
// Request pages to be allocated for paged hook details
|
||||
//
|
||||
PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
|
||||
Count,
|
||||
TRACKING_HOOKED_PAGES);
|
||||
PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
|
||||
Count,
|
||||
TRACKING_HOOKED_PAGES);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -199,7 +199,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
// Save the detail of hooked page to keep track of it
|
||||
//
|
||||
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
|
||||
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
|
||||
|
||||
if (!HookedPage)
|
||||
{
|
||||
|
|
@ -274,14 +274,14 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
// Split the 2MB page-table of each core to 4KB page-table
|
||||
//
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
//
|
||||
// We need to split the large page to 4KB page using pre-allocated pools
|
||||
//
|
||||
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
//
|
||||
// Here also other previous pools should be specified, but we forget it for now
|
||||
|
|
@ -302,7 +302,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
if (!TargetPage)
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
//
|
||||
// Here also other previous pools should be specified, but we forget it for now
|
||||
|
|
@ -907,7 +907,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
|
|||
//
|
||||
// Allocate some executable memory for the trampoline
|
||||
//
|
||||
Hook->Trampoline = (CHAR *)PoolManagerRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
|
||||
Hook->Trampoline = (CHAR *)PoolManagerCallbackRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
|
||||
|
||||
if (!Hook->Trampoline)
|
||||
{
|
||||
|
|
@ -956,7 +956,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
|
|||
// function that changes the original function and if our structure is no ready after this
|
||||
// function then we probably see BSOD on other cores
|
||||
//
|
||||
DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
|
||||
DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerCallbackRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
|
||||
DetourHookDetails->HookedFunctionAddress = TargetFunction;
|
||||
DetourHookDetails->ReturnAddress = Hook->Trampoline;
|
||||
|
||||
|
|
@ -1104,7 +1104,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
// Save the detail of hooked page to keep track of it
|
||||
//
|
||||
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
|
||||
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
|
||||
|
||||
if (!HookedPage)
|
||||
{
|
||||
|
|
@ -1155,7 +1155,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
|
||||
if (!HookedPage->StartOfTargetPhysicalAddress)
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
|
||||
return FALSE;
|
||||
|
|
@ -1183,7 +1183,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
|
||||
if (!HookedPage->EndOfTargetPhysicalAddress)
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
|
||||
return FALSE;
|
||||
|
|
@ -1244,21 +1244,21 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction))
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
VmmCallbackSetLastError(DEBUGGER_ERROR_COULD_NOT_BUILD_THE_EPT_HOOK);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
//
|
||||
// We need to split the large page to 4KB page using pre-allocated pools
|
||||
//
|
||||
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
//
|
||||
// Here also other previous pools should be specified, but we forget it for now
|
||||
|
|
@ -1278,7 +1278,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
if (!TargetPage)
|
||||
{
|
||||
PoolManagerFreePool((UINT64)HookedPage);
|
||||
PoolManagerCallbackFreePool((UINT64)HookedPage);
|
||||
|
||||
//
|
||||
// Here also other previous pools should be specified, but we forget it for now
|
||||
|
|
@ -1862,7 +1862,7 @@ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address)
|
|||
//
|
||||
// Free the pool in next ioctl
|
||||
//
|
||||
if (!PoolManagerFreePool((UINT64)CurrentHookedDetails))
|
||||
if (!PoolManagerCallbackFreePool((UINT64)CurrentHookedDetails))
|
||||
{
|
||||
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
|
||||
}
|
||||
|
|
@ -1964,7 +1964,7 @@ EptHookUnHookSingleAddressDetoursAndMonitor(PEPT_HOOKED_PAGE_DETAIL
|
|||
// we add the hooked entry to the list
|
||||
// of pools that will be deallocated on next IOCTL
|
||||
//
|
||||
if (!PoolManagerFreePool((UINT64)HookedEntry))
|
||||
if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
|
||||
{
|
||||
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
|
||||
return FALSE;
|
||||
|
|
@ -2069,7 +2069,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
|
|||
// is the HookedEntry that should be remove (not the first one as it has the
|
||||
// correct PreviousByte)
|
||||
//
|
||||
for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
|
||||
for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
|
||||
{
|
||||
if (HookedEntry->BreakpointAddresses[i] == VirtualAddress)
|
||||
{
|
||||
|
|
@ -2113,7 +2113,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
|
|||
// we add the hooked entry to the list
|
||||
// of pools that will be deallocated on next IOCTL
|
||||
//
|
||||
if (!PoolManagerFreePool((UINT64)HookedEntry))
|
||||
if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
|
||||
{
|
||||
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
|
||||
}
|
||||
|
|
@ -2162,7 +2162,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
|
|||
// in the array, then we'll ignore setting the previous bit as previous bit might
|
||||
// be modified for the previous command
|
||||
//
|
||||
for (size_t j = 0; j < HookedEntry->CountOfBreakpoints; j++)
|
||||
for (SIZE_T j = 0; j < HookedEntry->CountOfBreakpoints; j++)
|
||||
{
|
||||
if (HookedEntry->BreakpointAddresses[j] == VirtualAddress)
|
||||
{
|
||||
|
|
@ -2189,7 +2189,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
|
|||
// all addresses to a lower array index (because one entry is
|
||||
// missing and might) be in the middle of the array
|
||||
//
|
||||
for (size_t j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
|
||||
for (SIZE_T j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
|
||||
{
|
||||
HookedEntry->BreakpointAddresses[j] = HookedEntry->BreakpointAddresses[j + 1];
|
||||
HookedEntry->PreviousBytesOnBreakpointAddresses[j] = HookedEntry->PreviousBytesOnBreakpointAddresses[j + 1];
|
||||
|
|
@ -2274,7 +2274,7 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
|
|||
//
|
||||
// It's a hidden breakpoint
|
||||
//
|
||||
for (size_t i = 0; i < CurrEntity->CountOfBreakpoints; i++)
|
||||
for (SIZE_T i = 0; i < CurrEntity->CountOfBreakpoints; i++)
|
||||
{
|
||||
if (CurrEntity->BreakpointAddresses[i] == VirtualAddress)
|
||||
{
|
||||
|
|
@ -2485,7 +2485,7 @@ EptHookUnHookAll()
|
|||
// As we are in vmx-root here, we add the hooked entry to the list
|
||||
// of pools that will be deallocated on next IOCTL
|
||||
//
|
||||
if (!PoolManagerFreePool((UINT64)CurrEntity))
|
||||
if (!PoolManagerCallbackFreePool((UINT64)CurrEntity))
|
||||
{
|
||||
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 512; i++)
|
||||
for (SIZE_T i = 0; i < 512; i++)
|
||||
{
|
||||
// LogInfo("Address of Cr3Va: %llx", Cr3Va);
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
|
|||
//
|
||||
if (PdptVa != NULL)
|
||||
{
|
||||
for (size_t j = 0; j < 512; j++)
|
||||
for (SIZE_T j = 0; j < 512; j++)
|
||||
{
|
||||
// LogInfo("Address of PdptVa: %llx", PdptVa);
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
|
|||
//
|
||||
if (PdVa != NULL)
|
||||
{
|
||||
for (size_t k = 0; k < 512; k++)
|
||||
for (SIZE_T k = 0; k < 512; k++)
|
||||
{
|
||||
// LogInfo("Address of PdVa: %llx", PdVa);
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ ExecTrapTraverseThroughOsPageTables(PVMM_EPT_PAGE_TABLE EptTable, CR3_TYPE Targe
|
|||
//
|
||||
if (PtVa != NULL)
|
||||
{
|
||||
for (size_t l = 0; l < 512; l++)
|
||||
for (SIZE_T l = 0; l < 512; l++)
|
||||
{
|
||||
// LogInfo("Address of PtVa: %llx", PtVa);
|
||||
|
||||
|
|
@ -265,7 +265,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
{
|
||||
//
|
||||
// We only set the top-level PML4 for intercepting user-mode execution
|
||||
|
|
@ -276,7 +276,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML3s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
EptTable->PML3[i].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -284,9 +284,9 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML2s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
{
|
||||
EptTable->PML2[i][j].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -295,7 +295,7 @@ ExecTrapEnableExecuteOnlyPages(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// *** disallow read or write for certain memory only (not MMIO) EPTP pages ***
|
||||
//
|
||||
for (size_t i = 0; i < MAX_PHYSICAL_RAM_RANGE_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < MAX_PHYSICAL_RAM_RANGE_COUNT; i++)
|
||||
{
|
||||
if (PhysicalRamRegions[i].RamPhysicalAddress != NULL64_ZERO)
|
||||
{
|
||||
|
|
@ -482,7 +482,7 @@ ExecTrapRestoreToNormalEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Change EPTP
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_EPT_POINTER, VCpu->EptPointer.AsUInt);
|
||||
VmxVmwrite64(VMCS_CTRL_EPT_POINTER, VCpu->EptPointer.AsUInt);
|
||||
|
||||
//
|
||||
// It's on normal EPTP
|
||||
|
|
@ -510,7 +510,7 @@ ExecTrapChangeToUserDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
// for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// {
|
||||
VCpu->EptPageTable->PML4[0].UserModeExecute = FALSE;
|
||||
|
||||
|
|
@ -551,7 +551,7 @@ ExecTrapChangeToKernelDisabledMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
// for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// {
|
||||
VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
|
||||
|
||||
|
|
@ -592,7 +592,7 @@ ExecTrapChangeToNormalMbecEptp(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
// for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
// {
|
||||
VCpu->EptPageTable->PML4[0].UserModeExecute = TRUE;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
{
|
||||
//
|
||||
// We only set the top-level PML4 for intercepting user-mode execution
|
||||
|
|
@ -36,7 +36,7 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML3s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
EptTable->PML3[i].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -44,9 +44,9 @@ ModeBasedExecHookDisableUserModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML2s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
{
|
||||
EptTable->PML2[i][j].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -77,7 +77,7 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
{
|
||||
EptTable->PML4[i].UserModeExecute = TRUE;
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML3s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
EptTable->PML3[i].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -98,9 +98,9 @@ ModeBasedExecHookDisableKernelModeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML2s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
{
|
||||
EptTable->PML2[i][j].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -123,7 +123,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML4s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
{
|
||||
//
|
||||
// We only set the top-level PML4 for intercepting user-mode execution
|
||||
|
|
@ -134,7 +134,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML3s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
EptTable->PML3[i].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -142,9 +142,9 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML2s
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML3E_COUNT; i++)
|
||||
{
|
||||
for (size_t j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
for (SIZE_T j = 0; j < VMM_EPT_PML2E_COUNT; j++)
|
||||
{
|
||||
EptTable->PML2[i][j].UserModeExecute = TRUE;
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ ModeBasedExecHookEnableUsermodeExecution(PVMM_EPT_PAGE_TABLE EptTable)
|
|||
//
|
||||
// Set execute access for PML1s
|
||||
//
|
||||
for (size_t k = 0; k < VMM_EPT_PML1E_COUNT; k++)
|
||||
for (SIZE_T k = 0; k < VMM_EPT_PML1E_COUNT; k++)
|
||||
{
|
||||
Pml1Entries[k].UserModeExecute = TRUE;
|
||||
}
|
||||
|
|
@ -246,7 +246,7 @@ ModeBasedExecHookInitialize()
|
|||
//
|
||||
// Enable EPT user-mode execution bit for the target EPTP
|
||||
//
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
ModeBasedExecHookEnableUsermodeExecution(g_GuestState[i].EptPageTable);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file EferHook.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Implementation of the functions related to the EFER Syscall Hook
|
||||
|
|
@ -38,7 +38,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
|
|||
//
|
||||
// Reading IA32_VMX_BASIC_MSR
|
||||
//
|
||||
VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
|
||||
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
|
||||
|
||||
//
|
||||
// Read previous VM-Entry and VM-Exit controls
|
||||
|
|
@ -46,7 +46,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
|
|||
VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmEntryControls);
|
||||
VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmExitControls);
|
||||
|
||||
MsrValue.AsUInt = __readmsr(IA32_EFER);
|
||||
MsrValue.AsUInt = CpuReadMsr(IA32_EFER);
|
||||
|
||||
if (EnableEFERSyscallHook)
|
||||
{
|
||||
|
|
@ -55,17 +55,17 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
|
|||
//
|
||||
// Set VM-Entry controls to load EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
|
||||
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
|
||||
|
||||
//
|
||||
// Set VM-Exit controls to save EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
|
||||
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
|
||||
|
||||
//
|
||||
// Set the GUEST EFER to use this value as the EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
|
||||
VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
|
||||
|
||||
//
|
||||
// also, we have to set exception bitmap to cause vm-exit on #UDs
|
||||
|
|
@ -79,23 +79,23 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
|
|||
//
|
||||
// Set VM-Entry controls to load EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
|
||||
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
|
||||
|
||||
//
|
||||
// Set VM-Exit controls to save EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
|
||||
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
|
||||
|
||||
//
|
||||
// Set the GUEST EFER to use this value as the EFER
|
||||
//
|
||||
__vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
|
||||
VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
|
||||
|
||||
//
|
||||
// Because we're not save or load EFER on vm-exits so
|
||||
// we have to set it manually
|
||||
//
|
||||
__writemsr(IA32_EFER, MsrValue.AsUInt);
|
||||
CpuWriteMsr(IA32_EFER, MsrValue.AsUInt);
|
||||
|
||||
//
|
||||
// unset the exception to not cause vm-exit on #UDs
|
||||
|
|
@ -125,7 +125,7 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Reading guest's RIP
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
|
||||
|
||||
//
|
||||
// Reading instruction length
|
||||
|
|
@ -135,47 +135,47 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Reading guest's Rflags
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_RFLAGS, &GuestRflags);
|
||||
VmxVmread64P(VMCS_GUEST_RFLAGS, &GuestRflags);
|
||||
|
||||
//
|
||||
// Save the address of the instruction following SYSCALL into RCX and then
|
||||
// load RIP from IA32_LSTAR.
|
||||
//
|
||||
MsrValue = __readmsr(IA32_LSTAR);
|
||||
MsrValue = CpuReadMsr(IA32_LSTAR);
|
||||
VCpu->Regs->rcx = GuestRip + InstructionLength;
|
||||
GuestRip = MsrValue;
|
||||
__vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
|
||||
VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
|
||||
|
||||
//
|
||||
// Save RFLAGS into R11 and then mask RFLAGS using IA32_FMASK
|
||||
//
|
||||
MsrValue = __readmsr(IA32_FMASK);
|
||||
MsrValue = CpuReadMsr(IA32_FMASK);
|
||||
VCpu->Regs->r11 = GuestRflags;
|
||||
GuestRflags &= ~(MsrValue | X86_FLAGS_RF);
|
||||
__vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
|
||||
VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
|
||||
|
||||
//
|
||||
// Peform emulation of Intel CET (Shadow stacks)
|
||||
// Perform emulation of Intel CET (Shadow stacks)
|
||||
//
|
||||
if (g_CompatibilityCheck.CetShadowStackSupport)
|
||||
{
|
||||
UcetMsr.AsUInt = __readmsr(IA32_U_CET);
|
||||
UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
|
||||
|
||||
//
|
||||
// If the shadow stack is enabled, we have to save the current
|
||||
//
|
||||
if (UcetMsr.ShStkEn)
|
||||
{
|
||||
__vmx_vmread(VMCS_GUEST_SSP, &Ssp);
|
||||
__writemsr(IA32_PL3_SSP, Ssp);
|
||||
__vmx_vmwrite(VMCS_GUEST_SSP, 0);
|
||||
VmxVmread64P(VMCS_GUEST_SSP, &Ssp);
|
||||
CpuWriteMsr(IA32_PL3_SSP, Ssp);
|
||||
VmxVmwrite64(VMCS_GUEST_SSP, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Load the CS and SS selectors with values derived from bits 47:32 of IA32_STAR
|
||||
//
|
||||
MsrValue = __readmsr(IA32_STAR);
|
||||
MsrValue = CpuReadMsr(IA32_STAR);
|
||||
Cs.Selector = (UINT16)((MsrValue >> 32) & ~3); // STAR[47:32] & ~RPL3
|
||||
Cs.Base = 0; // flat segment
|
||||
Cs.Limit = (UINT32)~0; // 4GB limit
|
||||
|
|
@ -212,35 +212,35 @@ SyscallHookEmulateSYSRET(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// Load RIP from RCX
|
||||
//
|
||||
GuestRip = VCpu->Regs->rcx;
|
||||
__vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
|
||||
VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
|
||||
|
||||
//
|
||||
// Load RFLAGS from R11. Clear RF, VM, reserved bits
|
||||
//
|
||||
GuestRflags = (VCpu->Regs->r11 & ~(X86_FLAGS_RF | X86_FLAGS_VM | X86_FLAGS_RESERVED_BITS)) | X86_FLAGS_FIXED;
|
||||
__vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
|
||||
VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
|
||||
|
||||
//
|
||||
// Restore user-mode SPP
|
||||
//
|
||||
if (g_CompatibilityCheck.CetShadowStackSupport)
|
||||
{
|
||||
UcetMsr.AsUInt = __readmsr(IA32_U_CET);
|
||||
UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
|
||||
|
||||
//
|
||||
// If the shadow stack is enabled, we have to restore the current
|
||||
//
|
||||
if (UcetMsr.ShStkEn)
|
||||
{
|
||||
Ssp = __readmsr(IA32_PL3_SSP);
|
||||
__vmx_vmwrite(VMCS_GUEST_SSP, Ssp);
|
||||
Ssp = CpuReadMsr(IA32_PL3_SSP);
|
||||
VmxVmwrite64(VMCS_GUEST_SSP, Ssp);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// SYSRET loads the CS and SS selectors with values derived from bits 63:48 of IA32_STAR
|
||||
//
|
||||
MsrValue = __readmsr(IA32_STAR);
|
||||
MsrValue = CpuReadMsr(IA32_STAR);
|
||||
Cs.Selector = (UINT16)(((MsrValue >> 48) + 16) | 3); // (STAR[63:48]+16) | 3 (* RPL forced to 3 *)
|
||||
Cs.Base = 0; // Flat segment
|
||||
Cs.Limit = (UINT32)~0; // 4GB limit
|
||||
|
|
@ -273,7 +273,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Reading guest's RIP
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &Rip);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &Rip);
|
||||
|
||||
if (g_IsUnsafeSyscallOrSysretHandling)
|
||||
{
|
||||
|
|
@ -311,9 +311,9 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// if ((GuestCr3.Flags & PCID_MASK) != PCID_NONE)
|
||||
|
||||
OriginalCr3 = __readcr3();
|
||||
OriginalCr3 = CpuReadCr3();
|
||||
|
||||
__writecr3(GuestCr3.Flags);
|
||||
CpuWriteCr3(GuestCr3.Flags);
|
||||
|
||||
//
|
||||
// Read the memory
|
||||
|
|
@ -352,7 +352,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
__writecr3(OriginalCr3);
|
||||
CpuWriteCr3(OriginalCr3);
|
||||
|
||||
if (InstructionBuffer[0] == 0x0F &&
|
||||
InstructionBuffer[1] == 0x05)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
/**
|
||||
* @file SyscallCallback.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author jtaw5649
|
||||
* @brief Implementation of the functions related to the callback for Syscall
|
||||
* @details
|
||||
*
|
||||
|
|
@ -30,7 +31,7 @@ SyscallCallbackInitialize()
|
|||
//
|
||||
// Insert EPT memory page hook for Windows system call handler, KiSystemCall64()
|
||||
//
|
||||
Msr.Flags = __readmsr(IA32_LSTAR);
|
||||
Msr.Flags = CpuReadMsr(IA32_LSTAR);
|
||||
|
||||
//
|
||||
// We set the hook at the address of the system call handler + 3
|
||||
|
|
@ -75,6 +76,17 @@ SyscallCallbackInitialize()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the syscall callback is initialized
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
SyscallCallbackIsInitialized()
|
||||
{
|
||||
return g_SyscallCallbackStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Uninitialize the syscall callback
|
||||
*
|
||||
|
|
@ -86,9 +98,14 @@ SyscallCallbackUninitialize()
|
|||
if (g_SyscallCallbackStatus)
|
||||
{
|
||||
//
|
||||
// Disable the syscall callback
|
||||
// Unset the EPT hook from the syscall entry before disabling state.
|
||||
//
|
||||
g_SyscallCallbackStatus = FALSE;
|
||||
if (!ConfigureEptHookUnHookSingleAddress((UINT64)g_SystemCallHookAddress, (UINT64)NULL, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
|
||||
{
|
||||
LogInfo("Error while removing the EPT hook from windows syscall handler at address 0x%p", g_SystemCallHookAddress);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Unset the trap flags #DBs and #BPs for the syscall callback
|
||||
|
|
@ -100,15 +117,9 @@ SyscallCallbackUninitialize()
|
|||
//
|
||||
PlatformMemFreePool(g_SyscallCallbackTrapFlagState);
|
||||
|
||||
MSR Msr = {0};
|
||||
Msr.Flags = __readmsr(IA32_LSTAR);
|
||||
|
||||
if (!ConfigureEptHookUnHookSingleAddress((UINT64)(Msr.Flags + 3), (UINT64)NULL, (UINT32)(ULONG_PTR)PsGetCurrentProcessId()))
|
||||
{
|
||||
LogInfo("Error while removing the EPT hook from windows syscall handler at address 0x%p+3", Msr.Flags);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
g_SyscallCallbackTrapFlagState = NULL;
|
||||
g_SystemCallHookAddress = NULL;
|
||||
g_SyscallCallbackStatus = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,27 +86,6 @@ VmmCallbackVmcallHandler(UINT32 CoreId,
|
|||
return g_Callbacks.VmmCallbackVmcallHandler(CoreId, VmcallNumber, OptionalParam1, OptionalParam2, OptionalParam3);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to handle registered MTF
|
||||
*
|
||||
* @param CoreId
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmmCallbackRegisteredMtfHandler(UINT32 CoreId)
|
||||
{
|
||||
if (g_Callbacks.VmmCallbackRegisteredMtfHandler == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it
|
||||
//
|
||||
return;
|
||||
}
|
||||
|
||||
g_Callbacks.VmmCallbackRegisteredMtfHandler(CoreId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to handle NMI requests
|
||||
*
|
||||
|
|
@ -200,6 +179,47 @@ VmmCallbackUnhandledEptViolation(UINT32 CoreId,
|
|||
return g_Callbacks.VmmCallbackCheckUnhandledEptViolations(CoreId, ViolationQualification, GuestPhysicalAddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to handle MTF callback
|
||||
* @param CoreId
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
VmmCallbackHandleMtfCallback(UINT32 CoreId)
|
||||
{
|
||||
if (g_Callbacks.VmmCallbackHandleMtfCallback == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it as it's not handled
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return g_Callbacks.VmmCallbackHandleMtfCallback(CoreId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to check if LBR is supported and get the LBR capacity if supported
|
||||
*
|
||||
* @param Capacity
|
||||
* @param IsArchLbr
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HyperTraceCallbackLbrIsSupported(UINT32 * Capacity, BOOLEAN * IsArchLbr)
|
||||
{
|
||||
if (g_Callbacks.HyperTraceCallbackLbrIsSupported == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it as it's not handled
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return g_Callbacks.HyperTraceCallbackLbrIsSupported(Capacity, IsArchLbr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to handle breakpoint exception
|
||||
*
|
||||
|
|
@ -263,6 +283,110 @@ DebuggingCallbackCheckThreadInterception(UINT32 CoreId)
|
|||
return g_Callbacks.DebuggingCallbackCheckThreadInterception(CoreId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to trigger on clock and IPI events for checking process or thread change
|
||||
*
|
||||
* @param CoreId
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
DebuggingCallbackTriggerOnClockAndIpiEvents(UINT32 CoreId)
|
||||
{
|
||||
if (g_Callbacks.DebuggingCallbackTriggerOnClockAndIpiEvents == NULL)
|
||||
{
|
||||
//
|
||||
// not handled by user debugger
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return g_Callbacks.DebuggingCallbackTriggerOnClockAndIpiEvents(CoreId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to ignore handling mov 2 debug registers
|
||||
* @param CoreId
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
DebuggingCallbackIgnoreHandlingMov2DebugRegs(UINT32 CoreId)
|
||||
{
|
||||
if (g_Callbacks.DebuggingCallbackIgnoreHandlingMov2DebugRegs == NULL)
|
||||
{
|
||||
//
|
||||
// not handled by user debugger
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return g_Callbacks.DebuggingCallbackIgnoreHandlingMov2DebugRegs(CoreId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to request pool allocation
|
||||
*
|
||||
* @param Size
|
||||
* @param Count
|
||||
* @param Intention The intention of the buffer (buffer tag)
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
PoolManagerCallbackRequestAllocation(SIZE_T Size, UINT32 Count, POOL_ALLOCATION_INTENTION Intention)
|
||||
{
|
||||
if (g_Callbacks.PoolManagerCallbackRequestAllocation == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it as it's not handled
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return g_Callbacks.PoolManagerCallbackRequestAllocation(Size, Count, Intention);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to request pool
|
||||
*
|
||||
* @param Intention The intention why we need this pool for (buffer tag)
|
||||
* @param RequestNewPool Create a request to allocate a new pool with the same size, next time
|
||||
* that it's safe to allocate (this way we never ran out of pools for this "Intention")
|
||||
* @param Size If the RequestNewPool is true the we should specify a size for the new pool
|
||||
*
|
||||
* @return UINT64 Returns a pool address or returns null if there was an error
|
||||
*/
|
||||
UINT64
|
||||
PoolManagerCallbackRequestPool(POOL_ALLOCATION_INTENTION Intention, BOOLEAN RequestNewPool, UINT32 Size)
|
||||
{
|
||||
if (g_Callbacks.PoolManagerCallbackRequestPool == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it as it's not handled
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
return g_Callbacks.PoolManagerCallbackRequestPool(Intention, RequestNewPool, Size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to free pool
|
||||
*
|
||||
* @param AddressToFree
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
PoolManagerCallbackFreePool(UINT64 AddressToFree)
|
||||
{
|
||||
if (g_Callbacks.PoolManagerCallbackFreePool == NULL)
|
||||
{
|
||||
//
|
||||
// ignore it as it's not handled
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
return g_Callbacks.PoolManagerCallbackFreePool(AddressToFree);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief routine callback to handle cr3 process change
|
||||
*
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetM
|
|||
//
|
||||
// If the thread is intercepted, we should not trigger the event
|
||||
// Being here means that the thread should be handled by the user-mode debugger
|
||||
//
|
||||
// ou
|
||||
|
||||
// LogInfo("Thread Id: %x, process Id: %x is intercepted by user-mode debugger - RIP: %llx",
|
||||
// PsGetCurrentThreadId(),
|
||||
|
|
@ -711,13 +711,9 @@ DispatchEventMov2DebugRegs(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
BOOLEAN PostEventTriggerReq = FALSE;
|
||||
|
||||
//
|
||||
// Handle access to debug registers, if we should not ignore it, it is
|
||||
// because on detecting thread scheduling we ignore the hardware debug
|
||||
// registers modifications
|
||||
// Check to see if we should ignore handling the mov 2 debug registers or not
|
||||
//
|
||||
if (g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId != NULL &&
|
||||
g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(VCpu->CoreId,
|
||||
DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION))
|
||||
if (DebuggingCallbackIgnoreHandlingMov2DebugRegs(VCpu->CoreId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -850,7 +846,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// Check if we're waiting for an NMI on this core and if the guest is NOT in
|
||||
// a instrument step-in ('i' command) routine
|
||||
//
|
||||
if (!VCpu->RegisterBreakOnMtf &&
|
||||
if (!VCpu->InstrumentationStepInMtf &&
|
||||
VmxBroadcastNmiHandler(VCpu, FALSE))
|
||||
{
|
||||
return;
|
||||
|
|
@ -885,7 +881,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// So, we'll ignore the injection of Exception in this case
|
||||
//
|
||||
if (VCpu->RegisterBreakOnMtf)
|
||||
if (VCpu->InstrumentationStepInMtf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -974,10 +970,11 @@ DispatchEventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
if ((/* VCpu->CoreId == 0 && */ InterruptExit.Vector == CLOCK_INTERRUPT) ||
|
||||
(VCpu->CoreId != 0 && InterruptExit.Vector == IPI_INTERRUPT))
|
||||
{
|
||||
if (g_Callbacks.DebuggerCheckProcessOrThreadChange != NULL)
|
||||
{
|
||||
g_Callbacks.DebuggerCheckProcessOrThreadChange(VCpu->CoreId);
|
||||
}
|
||||
//
|
||||
// Calling the callback to trigger on clock and IPI events
|
||||
// This is usually used for detecting changes to processes and threads
|
||||
//
|
||||
DebuggingCallbackTriggerOnClockAndIpiEvents(VCpu->CoreId);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -63,29 +63,42 @@ VmFuncChangeIgnoreOneMtfState(UINT32 CoreId, BOOLEAN Set)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Register for break in the case of an MTF
|
||||
* @brief Set instrumentation step in MTF (used for single stepping with MTF)
|
||||
*
|
||||
* @param CoreId Target core's ID
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncRegisterMtfBreak(UINT32 CoreId)
|
||||
VmFuncSetInstrumentationStepInState(UINT32 CoreId)
|
||||
{
|
||||
g_GuestState[CoreId].RegisterBreakOnMtf = TRUE;
|
||||
g_GuestState[CoreId].InstrumentationStepInMtf = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister for break in the case of an MTF
|
||||
* @brief Unset instrumentation step in MTF (used for single stepping with MTF)
|
||||
*
|
||||
* @param CoreId Target core's ID
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncUnRegisterMtfBreak(UINT32 CoreId)
|
||||
VmFuncUnsetInstrumentationStepInState(UINT32 CoreId)
|
||||
{
|
||||
g_GuestState[CoreId].RegisterBreakOnMtf = FALSE;
|
||||
g_GuestState[CoreId].InstrumentationStepInMtf = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Query instrumentation step in MTF state
|
||||
*
|
||||
* @param CoreId Target core's ID
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
VmFuncQueryInstrumentationStepInState(UINT32 CoreId)
|
||||
{
|
||||
return g_GuestState[CoreId].InstrumentationStepInMtf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -115,25 +128,57 @@ VmFuncSetRflagTrapFlag(BOOLEAN Set)
|
|||
/**
|
||||
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
|
||||
*
|
||||
* @param CoreId target core id
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLoadDebugControls(BOOLEAN Set)
|
||||
VmFuncSetLoadDebugControls(UINT32 CoreId, BOOLEAN Set)
|
||||
{
|
||||
HvSetLoadDebugControls(Set);
|
||||
HvSetLoadDebugControls(&g_GuestState[CoreId], Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
|
||||
*
|
||||
* @param CoreId target core id
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLoadGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
|
||||
{
|
||||
HvSetLoadGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
|
||||
*
|
||||
* @param CoreId target core id
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetSaveDebugControls(BOOLEAN Set)
|
||||
VmFuncSetSaveDebugControls(UINT32 CoreId, BOOLEAN Set)
|
||||
{
|
||||
HvSetSaveDebugControls(Set);
|
||||
HvSetSaveDebugControls(&g_GuestState[CoreId], Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-exit controls
|
||||
*
|
||||
* @param CoreId target core id
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetClearGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
|
||||
{
|
||||
HvSetClearGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -389,6 +434,211 @@ VmFuncSetRip(UINT64 Rip)
|
|||
HvSetRip(Rip);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_DEBUGCTL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
VmFuncGetDebugctl()
|
||||
{
|
||||
return HvGetDebugctl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_DEBUGCTL on the target core from VMCS
|
||||
* using VMCALL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
VmFuncGetDebugctlVmcallOnTargetCore()
|
||||
{
|
||||
return CrossVmcallGetDebugctlVmcallOnTargetCore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_LBR_CTL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
VmFuncGetGuestIa32LbrCtl()
|
||||
{
|
||||
return HvGetGuestIa32LbrCtl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_LBR_CTL on the target core from VMCS
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore()
|
||||
{
|
||||
return CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if CPU support save and load debug controls on exit and load entries
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
VmFuncCheckCpuSupportForSaveAndLoadDebugControls()
|
||||
{
|
||||
return HvCheckCpuSupportForSaveAndLoadDebugControls();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on VM-entry and VM-exit
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
|
||||
{
|
||||
return HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_DEBUGCTL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetDebugctl(UINT64 Value)
|
||||
{
|
||||
HvSetDebugctl(Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_DEBUGCTL on the target core from VMCS
|
||||
* using VMCALL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetDebugctlVmcallOnTargetCore(UINT64 Value)
|
||||
{
|
||||
CrossVmcallSetDebugctlVmcallOnTargetCore(Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_LBR_CTL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetGuestIa32LbrCtl(UINT64 Value)
|
||||
{
|
||||
HvSetGuestIa32LbrCtl(Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_LBR_CTL on the target core from VMCS
|
||||
* using VMCALL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value)
|
||||
{
|
||||
CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of MSR_LEGACY_LBR_SELECT
|
||||
* @param FilterOptions
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLbrSelect(UINT64 FilterOptions)
|
||||
{
|
||||
HvSetLbrSelect(FilterOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of MSR_LEGACY_LBR_SELECT on the target core from VMCS using VMCALL
|
||||
* @param FilterOptions
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions)
|
||||
{
|
||||
CrossVmcallSetLbrSelectVmcallOnTargetCore(FilterOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LOAD DEBUG CONTROLS on VM-entry controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LOAD GUEST IA32_LBR_CTL on VM-entry controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAVE DEBUG CONTROLS on VM-exit controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CLEAR GUEST IA32_LBR_CTL on VM-exit controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of DR7
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
VmFuncSetDebugReg7(UINT64 Value)
|
||||
{
|
||||
HvSetDebugReg7(Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read guest's interruptibility state
|
||||
*
|
||||
|
|
@ -620,7 +870,7 @@ VmFuncVmxCompatibleStrlen(const CHAR * s)
|
|||
* @return UINT32
|
||||
*/
|
||||
UINT32
|
||||
VmFuncVmxCompatibleWcslen(const wchar_t * s)
|
||||
VmFuncVmxCompatibleWcslen(const WCHAR * s)
|
||||
{
|
||||
return VmxCompatibleWcslen(s);
|
||||
}
|
||||
|
|
@ -704,10 +954,10 @@ VmFuncEventInjectInterruption(UINT32 InterruptionType,
|
|||
* @return NTSTATUS
|
||||
*/
|
||||
NTSTATUS
|
||||
VmFuncVmxVmcall(unsigned long long VmcallNumber,
|
||||
unsigned long long OptionalParam1,
|
||||
unsigned long long OptionalParam2,
|
||||
unsigned long long OptionalParam3)
|
||||
VmFuncVmxVmcall(UINT64 VmcallNumber,
|
||||
UINT64 OptionalParam1,
|
||||
UINT64 OptionalParam2,
|
||||
UINT64 OptionalParam3)
|
||||
{
|
||||
return AsmVmxVmcall(VmcallNumber, OptionalParam1, OptionalParam2, OptionalParam3);
|
||||
}
|
||||
|
|
@ -780,7 +1030,7 @@ VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T
|
|||
* @return INT32
|
||||
*/
|
||||
INT32
|
||||
VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
|
||||
VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2)
|
||||
{
|
||||
return VmxCompatibleWcscmp(Address1, Address2, NULL_ZERO, FALSE);
|
||||
}
|
||||
|
|
@ -794,7 +1044,7 @@ VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
|
|||
* @return INT32
|
||||
*/
|
||||
INT32
|
||||
VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, SIZE_T Num)
|
||||
VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num)
|
||||
{
|
||||
return VmxCompatibleWcscmp(Address1, Address2, Num, TRUE);
|
||||
}
|
||||
|
|
@ -808,14 +1058,14 @@ VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, S
|
|||
* @return INT32
|
||||
*/
|
||||
INT32
|
||||
VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
|
||||
VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count)
|
||||
{
|
||||
return VmxCompatibleMemcmp(Address1, Address2, Count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables MTF and adjust external interrupt state
|
||||
* @param UINT32 CoreId
|
||||
* @param CoreId
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
|
|
@ -828,7 +1078,7 @@ VmFuncEnableMtfAndChangeExternalInterruptState(UINT32 CoreId)
|
|||
/**
|
||||
* @brief Checks to enable and reinject previous interrupts
|
||||
*
|
||||
* @param UINT32 CoreId
|
||||
* @param CoreId
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* @file HyperEvade.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author jtaw5649
|
||||
* @brief Hyperevade function wrappers
|
||||
* @details
|
||||
*
|
||||
|
|
@ -24,6 +25,20 @@ BOOLEAN
|
|||
TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
|
||||
{
|
||||
HYPEREVADE_CALLBACKS HyperevadeCallbacks = {0};
|
||||
UINT32 EvadeMask = TransparentModeRequest->EvadeMask;
|
||||
|
||||
if (EvadeMask == 0)
|
||||
{
|
||||
EvadeMask = TRANSPARENT_EVADE_MASK_DEFAULT;
|
||||
}
|
||||
|
||||
if ((EvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
|
||||
{
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TransparentModeRequest->EvadeMask = EvadeMask;
|
||||
|
||||
//
|
||||
// *** Fill the callbacks ***
|
||||
|
|
@ -38,6 +53,11 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
|
|||
HyperevadeCallbacks.LogCallbackSendBuffer = g_Callbacks.LogCallbackSendBuffer;
|
||||
HyperevadeCallbacks.LogCallbackCheckIfBufferIsFull = g_Callbacks.LogCallbackCheckIfBufferIsFull;
|
||||
|
||||
//
|
||||
// HyperTrace callback(s)
|
||||
//
|
||||
HyperevadeCallbacks.HyperTraceLbrIsSupported = HyperTraceCallbackLbrIsSupported;
|
||||
|
||||
//
|
||||
// Memory callbacks
|
||||
//
|
||||
|
|
@ -61,20 +81,24 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
|
|||
HyperevadeCallbacks.HvHandleTrapFlag = HvHandleTrapFlag;
|
||||
HyperevadeCallbacks.EventInjectGeneralProtection = EventInjectGeneralProtection;
|
||||
|
||||
//
|
||||
// Initialize the syscall callback mechanism from hypervisor
|
||||
//
|
||||
if (!SyscallCallbackInitialize())
|
||||
{
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Call the hyperevade hide debugger function
|
||||
//
|
||||
if (TransparentHideDebugger(&HyperevadeCallbacks, TransparentModeRequest))
|
||||
{
|
||||
//
|
||||
// Initialize the syscall callback mechanism from hypervisor after
|
||||
// transparent-mode accepts the request as the active state.
|
||||
//
|
||||
if ((EvadeMask & TRANSPARENT_EVADE_MASK_SYSCALL_HOOK) != 0 && !SyscallCallbackInitialize())
|
||||
{
|
||||
TransparentUnhideDebugger();
|
||||
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
|
||||
g_CheckForFootprints = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Status is set within the transparent mode (hyperevade) module
|
||||
//
|
||||
|
|
@ -100,10 +124,15 @@ TransparentHideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * Tra
|
|||
BOOLEAN
|
||||
TransparentUnhideDebuggerWrapper(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
|
||||
{
|
||||
//
|
||||
// Unitialize the syscall callback mechanism from hypervisor
|
||||
//
|
||||
SyscallCallbackUninitialize();
|
||||
if (SyscallCallbackIsInitialized() && !SyscallCallbackUninitialize())
|
||||
{
|
||||
if (TransparentModeRequest != NULL)
|
||||
{
|
||||
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (TransparentUnhideDebugger())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*
|
||||
* @param Address Address to check
|
||||
*
|
||||
* @param UINT32 ProcId
|
||||
* @param ProcId
|
||||
* @return BOOLEAN Returns true if the address is valid; otherwise, false
|
||||
*/
|
||||
BOOLEAN
|
||||
|
|
@ -192,8 +192,8 @@ CheckAccessValidityAndSafetyWrapper(UINT64 TargetAddress, UINT32 Size, UINT32 Pr
|
|||
//
|
||||
// Move to new cr3
|
||||
//
|
||||
OriginalCr3 = __readcr3();
|
||||
__writecr3(GuestCr3.Flags);
|
||||
OriginalCr3 = CpuReadCr3();
|
||||
CpuWriteCr3(GuestCr3.Flags);
|
||||
|
||||
//
|
||||
// We'll only check address with TSX if the address is a kernel-mode
|
||||
|
|
@ -210,7 +210,7 @@ CheckAccessValidityAndSafetyWrapper(UINT64 TargetAddress, UINT32 Size, UINT32 Pr
|
|||
// UINT64 AlignedPage = (UINT64)PAGE_ALIGN(TargetAddress);
|
||||
// UINT64 PageCount = ((TargetAddress - AlignedPage) + Size) / PAGE_SIZE;
|
||||
//
|
||||
// for (size_t i = 0; i <= PageCount; i++)
|
||||
// for (SIZE_T i = 0; i <= PageCount; i++)
|
||||
// {
|
||||
// UINT64 CheckAddr = AlignedPage + (PAGE_SIZE * i);
|
||||
// if (!CheckAddressValidityUsingTsx(CheckAddr))
|
||||
|
|
@ -301,7 +301,7 @@ RestoreCr3:
|
|||
//
|
||||
// Move back to original cr3
|
||||
//
|
||||
__writecr3(OriginalCr3);
|
||||
CpuWriteCr3(OriginalCr3);
|
||||
|
||||
Return:
|
||||
return Result;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ LayoutGetExactGuestProcessCr3()
|
|||
{
|
||||
CR3_TYPE GuestCr3 = {0};
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR3, &GuestCr3.Flags);
|
||||
VmxVmread64P(VMCS_GUEST_CR3, &GuestCr3.Flags);
|
||||
|
||||
return GuestCr3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ MemoryMapperGetPteVa(PVOID Va, PAGING_LEVEL Level)
|
|||
//
|
||||
// Read the current cr3
|
||||
//
|
||||
Cr3.Flags = __readcr3();
|
||||
Cr3.Flags = CpuReadCr3();
|
||||
|
||||
//
|
||||
// Call the wrapper
|
||||
|
|
@ -287,7 +287,7 @@ MemoryMapperSetExecuteDisableToPteOnTargetProcess(PVOID Va, BOOLEAN Set)
|
|||
//
|
||||
// Invalidate the TLB
|
||||
//
|
||||
__invlpg(Va);
|
||||
CpuInvlpg(Va);
|
||||
|
||||
//
|
||||
// Restore the original process
|
||||
|
|
@ -685,7 +685,7 @@ MemoryMapperInitialize()
|
|||
//
|
||||
// Set the core's id and initialize memory mapper
|
||||
//
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
//
|
||||
// *** Initialize memory mapper for each core ***
|
||||
|
|
@ -717,7 +717,7 @@ MemoryMapperUninitialize()
|
|||
{
|
||||
ULONG ProcessorsCount = KeQueryActiveProcessorCount(0);
|
||||
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
//
|
||||
// Unmap and free the reserved buffer
|
||||
|
|
@ -804,7 +804,7 @@ MemoryMapperReadMemorySafeByPte(PHYSICAL_ADDRESS PaAddressToRead,
|
|||
// because it will be automatically invalidated by the top hypervisor, however,
|
||||
// we should use invlpg in physical computers as it won't invalidate it automatically
|
||||
//
|
||||
__invlpg(Va);
|
||||
CpuInvlpg(Va);
|
||||
|
||||
//
|
||||
// Also invalidate it from vpids if we're in vmx root
|
||||
|
|
@ -888,7 +888,7 @@ MemoryMapperWriteMemorySafeByPte(PVOID SourceVA,
|
|||
//
|
||||
// Finally, invalidate the caches for the virtual address.
|
||||
//
|
||||
__invlpg(Va);
|
||||
CpuInvlpg(Va);
|
||||
|
||||
//
|
||||
// Also invalidate it from vpids if we're in vmx root
|
||||
|
|
@ -1180,8 +1180,8 @@ MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferTo
|
|||
//
|
||||
// Move to new cr3
|
||||
//
|
||||
OriginalCr3.Flags = __readcr3();
|
||||
__writecr3(GuestCr3.Flags);
|
||||
OriginalCr3.Flags = CpuReadCr3();
|
||||
CpuWriteCr3(GuestCr3.Flags);
|
||||
|
||||
//
|
||||
// Read target memory
|
||||
|
|
@ -1191,7 +1191,7 @@ MemoryMapperReadMemorySafeOnTargetProcess(UINT64 VaAddressToRead, PVOID BufferTo
|
|||
//
|
||||
// Move back to original cr3
|
||||
//
|
||||
__writecr3(OriginalCr3.Flags);
|
||||
CpuWriteCr3(OriginalCr3.Flags);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
|
@ -1225,8 +1225,8 @@ MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZ
|
|||
//
|
||||
// Move to new cr3
|
||||
//
|
||||
OriginalCr3.Flags = __readcr3();
|
||||
__writecr3(GuestCr3.Flags);
|
||||
OriginalCr3.Flags = CpuReadCr3();
|
||||
CpuWriteCr3(GuestCr3.Flags);
|
||||
|
||||
//
|
||||
// Write target memory
|
||||
|
|
@ -1236,7 +1236,7 @@ MemoryMapperWriteMemorySafeOnTargetProcess(UINT64 Destination, PVOID Source, SIZ
|
|||
//
|
||||
// Move back to original cr3
|
||||
//
|
||||
__writecr3(OriginalCr3.Flags);
|
||||
CpuWriteCr3(OriginalCr3.Flags);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
|
@ -1720,7 +1720,7 @@ MemoryMapperMapPhysicalAddressToPte(PHYSICAL_ADDRESS PhysicalAddress,
|
|||
// because it will be automatically invalidated by the top hypervisor, however,
|
||||
// we should use invlpg in physical computers as it won't invalidate it automatically
|
||||
//
|
||||
__invlpg(TargetProcessVirtualAddress);
|
||||
CpuInvlpg(TargetProcessVirtualAddress);
|
||||
|
||||
//
|
||||
// Restore the original process
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file Segmentation.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Functions for handling memory segmentations
|
||||
|
|
@ -47,7 +47,7 @@ SegmentGetDescriptor(PUCHAR GdtBase,
|
|||
Descriptor32 = &DescriptorTable32[SegSelector.Index];
|
||||
|
||||
SegmentSelector->Selector = Selector;
|
||||
SegmentSelector->Limit = __segmentlimit(Selector);
|
||||
SegmentSelector->Limit = CpuSegmentLimit(Selector);
|
||||
SegmentSelector->Base = ((UINT64)Descriptor32->BaseAddressLow | (UINT64)Descriptor32->BaseAddressMiddle << 16 | (UINT64)Descriptor32->BaseAddressHigh << 24);
|
||||
|
||||
SegmentSelector->Attributes.AsUInt = (AsmGetAccessRights(Selector) >> 8);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file SwitchLayout.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Functions for switching memory layouts
|
||||
|
|
@ -46,12 +46,12 @@ SwitchToProcessMemoryLayout(UINT32 ProcessId)
|
|||
//
|
||||
// Read the current cr3
|
||||
//
|
||||
CurrentProcessCr3.Flags = __readcr3();
|
||||
CurrentProcessCr3.Flags = CpuReadCr3();
|
||||
|
||||
//
|
||||
// Change to a new cr3 (of target process)
|
||||
//
|
||||
__writecr3(GuestCr3);
|
||||
CpuWriteCr3(GuestCr3);
|
||||
|
||||
ObDereferenceObject(TargetEprocess);
|
||||
|
||||
|
|
@ -77,12 +77,12 @@ SwitchToCurrentProcessMemoryLayout()
|
|||
//
|
||||
// Read the current cr3
|
||||
//
|
||||
CurrentProcessCr3.Flags = __readcr3();
|
||||
CurrentProcessCr3.Flags = CpuReadCr3();
|
||||
|
||||
//
|
||||
// Change to a new cr3 (of target process)
|
||||
//
|
||||
__writecr3(GuestCr3.Flags);
|
||||
CpuWriteCr3(GuestCr3.Flags);
|
||||
|
||||
return CurrentProcessCr3;
|
||||
}
|
||||
|
|
@ -103,12 +103,12 @@ SwitchToProcessMemoryLayoutByCr3(CR3_TYPE TargetCr3)
|
|||
//
|
||||
// Read the current cr3
|
||||
//
|
||||
CurrentProcessCr3.Flags = __readcr3();
|
||||
CurrentProcessCr3.Flags = CpuReadCr3();
|
||||
|
||||
//
|
||||
// Change to a new cr3 (of target process)
|
||||
//
|
||||
__writecr3(TargetCr3.Flags);
|
||||
CpuWriteCr3(TargetCr3.Flags);
|
||||
|
||||
return CurrentProcessCr3;
|
||||
}
|
||||
|
|
@ -127,5 +127,5 @@ SwitchToPreviousProcess(CR3_TYPE PreviousProcess)
|
|||
//
|
||||
// Restore the original cr3
|
||||
//
|
||||
__writecr3(PreviousProcess.Flags);
|
||||
CpuWriteCr3(PreviousProcess.Flags);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file Idt.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Routines for Interrupt Descriptor Table
|
||||
|
|
@ -21,7 +21,7 @@ VOID
|
|||
IdtDumpInterruptEntries()
|
||||
{
|
||||
KDESCRIPTOR64 descr;
|
||||
__sidt(&descr.Limit);
|
||||
CpuSidt(&descr.Limit);
|
||||
|
||||
ULONG n = (descr.Limit + 1) / sizeof(KIDTENTRY64);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file Smm.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Routines for operations related to System Management Mode (SMM)
|
||||
|
|
@ -25,7 +25,7 @@ SmmReadSmiCount()
|
|||
//
|
||||
// Read the SMI count from MSR
|
||||
//
|
||||
SmiCount = (UINT64)__readmsr(MSR_SMI_COUNT);
|
||||
SmiCount = (UINT64)CpuReadMsr(MSR_SMI_COUNT);
|
||||
|
||||
return SmiCount;
|
||||
}
|
||||
|
|
@ -43,17 +43,17 @@ SmmTriggerPowerSmi()
|
|||
//
|
||||
// check the initial value received from 0xB3 port
|
||||
//
|
||||
SmmResponse = __inbyte(0xb2);
|
||||
SmmResponse = CpuIoInByte(0xb2);
|
||||
|
||||
//
|
||||
// write to 0xB2 port to cause SMI
|
||||
//
|
||||
__outbyte(0xb2, SMI_TRIGGER_POWER_VALUE);
|
||||
CpuIoOutByte(0xb2, SMI_TRIGGER_POWER_VALUE);
|
||||
|
||||
//
|
||||
// Check the respose in port 0xB3
|
||||
// Check the response in port 0xB3
|
||||
//
|
||||
SmmResponse = __inbyte(0xb2);
|
||||
SmmResponse = CpuIoInByte(0xb2);
|
||||
|
||||
if (SmmResponse == SMI_TRIGGER_POWER_VALUE)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ EptCheckFeatures(VOID)
|
|||
{
|
||||
IA32_VMX_EPT_VPID_CAP_REGISTER VpidRegister;
|
||||
IA32_MTRR_DEF_TYPE_REGISTER MTRRDefType;
|
||||
|
||||
VpidRegister.AsUInt = __readmsr(IA32_VMX_EPT_VPID_CAP);
|
||||
MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
|
||||
g_IsVpidSupported = FALSE;
|
||||
VpidRegister.AsUInt = CpuReadMsr(IA32_VMX_EPT_VPID_CAP);
|
||||
MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
|
||||
|
||||
if (!VpidRegister.PageWalkLength4 || !VpidRegister.MemoryTypeWriteBack || !VpidRegister.Pde2MbPages)
|
||||
{
|
||||
|
|
@ -37,6 +37,17 @@ EptCheckFeatures(VOID)
|
|||
LogDebugInfo("The processor doesn't report advanced VM-exit information for EPT violations");
|
||||
}
|
||||
|
||||
if (VpidRegister.Invvpid &&
|
||||
VpidRegister.InvvpidAllContexts &&
|
||||
VpidRegister.InvvpidIndividualAddress &&
|
||||
VpidRegister.InvvpidSingleContext &&
|
||||
VpidRegister.InvvpidSingleContextRetainGlobals &&
|
||||
!g_IsTopLevelHypervisorHyperV)
|
||||
{
|
||||
g_IsVpidSupported = TRUE;
|
||||
LogDebugInfo("The processor supports VPID");
|
||||
}
|
||||
|
||||
if (!VpidRegister.ExecuteOnlyPages)
|
||||
{
|
||||
g_CompatibilityCheck.ExecuteOnlySupport = FALSE;
|
||||
|
|
@ -163,8 +174,8 @@ EptBuildMtrrMap(VOID)
|
|||
UINT32 CurrentRegister;
|
||||
UINT32 NumberOfBitsInMask;
|
||||
|
||||
MTRRCap.AsUInt = __readmsr(IA32_MTRR_CAPABILITIES);
|
||||
MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
|
||||
MTRRCap.AsUInt = CpuReadMsr(IA32_MTRR_CAPABILITIES);
|
||||
MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
|
||||
|
||||
//
|
||||
// All MTRRs are disabled when clear, and the
|
||||
|
|
@ -200,8 +211,8 @@ EptBuildMtrrMap(VOID)
|
|||
{
|
||||
const UINT32 K64Base = 0x0;
|
||||
const UINT32 K64Size = 0x10000;
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K64Types = {__readmsr(IA32_MTRR_FIX64K_00000)};
|
||||
for (unsigned int i = 0; i < 8; i++)
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K64Types = {CpuReadMsr(IA32_MTRR_FIX64K_00000)};
|
||||
for (UINT32 i = 0; i < 8; i++)
|
||||
{
|
||||
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
|
||||
Descriptor->MemoryType = K64Types.s.Types[i];
|
||||
|
|
@ -212,10 +223,10 @@ EptBuildMtrrMap(VOID)
|
|||
|
||||
const UINT32 K16Base = 0x80000;
|
||||
const UINT32 K16Size = 0x4000;
|
||||
for (unsigned int i = 0; i < 2; i++)
|
||||
for (UINT32 i = 0; i < 2; i++)
|
||||
{
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K16Types = {__readmsr(IA32_MTRR_FIX16K_80000 + i)};
|
||||
for (unsigned int j = 0; j < 8; j++)
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K16Types = {CpuReadMsr(IA32_MTRR_FIX16K_80000 + i)};
|
||||
for (UINT32 j = 0; j < 8; j++)
|
||||
{
|
||||
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
|
||||
Descriptor->MemoryType = K16Types.s.Types[j];
|
||||
|
|
@ -227,11 +238,11 @@ EptBuildMtrrMap(VOID)
|
|||
|
||||
const UINT32 K4Base = 0xC0000;
|
||||
const UINT32 K4Size = 0x1000;
|
||||
for (unsigned int i = 0; i < 8; i++)
|
||||
for (UINT32 i = 0; i < 8; i++)
|
||||
{
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K4Types = {__readmsr(IA32_MTRR_FIX4K_C0000 + i)};
|
||||
IA32_MTRR_FIXED_RANGE_TYPE K4Types = {CpuReadMsr(IA32_MTRR_FIX4K_C0000 + i)};
|
||||
|
||||
for (unsigned int j = 0; j < 8; j++)
|
||||
for (UINT32 j = 0; j < 8; j++)
|
||||
{
|
||||
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
|
||||
Descriptor->MemoryType = K4Types.s.Types[j];
|
||||
|
|
@ -247,8 +258,8 @@ EptBuildMtrrMap(VOID)
|
|||
//
|
||||
// For each dynamic register pair
|
||||
//
|
||||
CurrentPhysBase.AsUInt = __readmsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
|
||||
CurrentPhysMask.AsUInt = __readmsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
|
||||
CurrentPhysBase.AsUInt = CpuReadMsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
|
||||
CurrentPhysMask.AsUInt = CpuReadMsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
|
||||
|
||||
//
|
||||
// Is the range enabled?
|
||||
|
|
@ -270,7 +281,7 @@ EptBuildMtrrMap(VOID)
|
|||
// Calculate the total size of the range
|
||||
// The lowest bit of the mask that is set to 1 specifies the size of the range
|
||||
//
|
||||
_BitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
|
||||
CpuBitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
|
||||
|
||||
//
|
||||
// Size of the range in bytes + Base Address
|
||||
|
|
@ -293,6 +304,28 @@ EptBuildMtrrMap(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resolve the split PML1 VA that belongs to a given PML2 entry
|
||||
*
|
||||
* @param EptPageTable The EPT page table
|
||||
* @param TargetEntry The target PML2 entry
|
||||
* @return PEPT_PML1_ENTRY Returns base VA of PML1 page, or NULL if not tracked
|
||||
*/
|
||||
_Must_inspect_result_
|
||||
static PEPT_PML1_ENTRY
|
||||
EptGetSplitPml1VaByPml2Entry(_In_ PVMM_EPT_PAGE_TABLE EptPageTable, _In_ PEPT_PML2_ENTRY TargetEntry)
|
||||
{
|
||||
LIST_FOR_EACH_LINK(EptPageTable->DynamicSplitList, VMM_EPT_DYNAMIC_SPLIT, DynamicSplitList, CurrentSplit)
|
||||
{
|
||||
if (CurrentSplit->Fields.Entry == TargetEntry)
|
||||
{
|
||||
return &CurrentSplit->PML1[0];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PML1 entry for this physical address if the page is split
|
||||
*
|
||||
|
|
@ -303,10 +336,9 @@ EptBuildMtrrMap(VOID)
|
|||
PEPT_PML1_ENTRY
|
||||
EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
|
||||
{
|
||||
SIZE_T Directory, DirectoryPointer, PML4Entry;
|
||||
PEPT_PML2_ENTRY PML2;
|
||||
PEPT_PML1_ENTRY PML1;
|
||||
PEPT_PML2_POINTER PML2Pointer;
|
||||
SIZE_T Directory, DirectoryPointer, PML4Entry;
|
||||
PEPT_PML2_ENTRY PML2;
|
||||
PEPT_PML1_ENTRY PML1;
|
||||
|
||||
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
|
||||
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
|
||||
|
|
@ -331,15 +363,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
|
|||
}
|
||||
|
||||
//
|
||||
// Conversion to get the right PageFrameNumber.
|
||||
// These pointers occupy the same place in the table and are directly convertible.
|
||||
// Resolve the split PML1 VA that was recorded during EptSplitLargePage
|
||||
//
|
||||
PML2Pointer = (PEPT_PML2_POINTER)PML2;
|
||||
|
||||
//
|
||||
// If it is, translate to the PML1 pointer
|
||||
//
|
||||
PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
|
||||
PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
|
||||
|
||||
if (!PML1)
|
||||
{
|
||||
|
|
@ -367,10 +393,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
|
|||
PVOID
|
||||
EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress, BOOLEAN * IsLargePage)
|
||||
{
|
||||
SIZE_T Directory, DirectoryPointer, PML4Entry;
|
||||
PEPT_PML2_ENTRY PML2;
|
||||
PEPT_PML1_ENTRY PML1;
|
||||
PEPT_PML2_POINTER PML2Pointer;
|
||||
SIZE_T Directory, DirectoryPointer, PML4Entry;
|
||||
PEPT_PML2_ENTRY PML2;
|
||||
PEPT_PML1_ENTRY PML1;
|
||||
|
||||
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
|
||||
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
|
||||
|
|
@ -396,15 +421,9 @@ EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress,
|
|||
}
|
||||
|
||||
//
|
||||
// Conversion to get the right PageFrameNumber.
|
||||
// These pointers occupy the same place in the table and are directly convertible.
|
||||
// Resolve the split PML1 VA that was recorded during EptSplitLargePage
|
||||
//
|
||||
PML2Pointer = (PEPT_PML2_POINTER)PML2;
|
||||
|
||||
//
|
||||
// If it is, translate to the PML1 pointer
|
||||
//
|
||||
PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
|
||||
PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
|
||||
|
||||
if (!PML1)
|
||||
{
|
||||
|
|
@ -494,7 +513,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
//
|
||||
if (UsePreAllocatedBuffer)
|
||||
{
|
||||
NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
|
||||
NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerCallbackRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -512,7 +531,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
// Point back to the entry in the dynamic split for easy reference for which entry that
|
||||
// dynamic split is for
|
||||
//
|
||||
NewSplit->u.Entry = TargetEntry;
|
||||
NewSplit->Fields.Entry = TargetEntry;
|
||||
|
||||
//
|
||||
// Make a template for RWX
|
||||
|
|
@ -544,7 +563,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
//
|
||||
// Copy the template into all the PML1 entries
|
||||
//
|
||||
__stosq((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
|
||||
CpuStosQ((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
|
||||
|
||||
//
|
||||
// Set the page frame numbers for identity mapping
|
||||
|
|
@ -585,6 +604,12 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
|
|||
//
|
||||
RtlCopyMemory(TargetEntry, &NewPointer, sizeof(NewPointer));
|
||||
|
||||
//
|
||||
// Track the split so we can directly resolve PML1 VA from PML2 entry
|
||||
// without any PA->VA reverse translation
|
||||
//
|
||||
InsertHeadList(&EptPageTable->DynamicSplitList, &(NewSplit->DynamicSplitList));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -684,6 +709,11 @@ EptAllocateAndCreateIdentityPageTable(VOID)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Keep track of dynamic 2MB->4KB split metadata for this EPT table.
|
||||
//
|
||||
InitializeListHead(&PageTable->DynamicSplitList);
|
||||
|
||||
//
|
||||
// Create the template for the first entry in the PML4
|
||||
//
|
||||
|
|
@ -694,7 +724,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
|
|||
//
|
||||
// Copy the template into each of the 512 PML4 entry slots
|
||||
//
|
||||
__stosq((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
|
||||
CpuStosQ((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
|
||||
|
||||
for (int i = 0; i < VMM_EPT_PML4E_COUNT; i++)
|
||||
{
|
||||
|
|
@ -739,14 +769,14 @@ EptAllocateAndCreateIdentityPageTable(VOID)
|
|||
//
|
||||
// Copy the template into each of the 512 PML3 entry slots for the original entries
|
||||
//
|
||||
__stosq((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
|
||||
CpuStosQ((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
|
||||
|
||||
//
|
||||
// Copt the template into each of the 512 PML3 entry slots for the reserved entries
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
|
||||
{
|
||||
__stosq((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
|
||||
CpuStosQ((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -764,9 +794,9 @@ EptAllocateAndCreateIdentityPageTable(VOID)
|
|||
//
|
||||
// For each of the 512 PML3 reserved entries for reserved PML3 entries
|
||||
//
|
||||
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
|
||||
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
|
||||
{
|
||||
for (size_t j = 0; j < VMM_EPT_PML3E_COUNT; j++)
|
||||
for (SIZE_T j = 0; j < VMM_EPT_PML3E_COUNT; j++)
|
||||
{
|
||||
//
|
||||
// Map the 1GB PML3 reserved entry to 512 PML3 (1GB) entries to describe each large page
|
||||
|
|
@ -803,7 +833,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
|
|||
// this region or not. We will cause a fault in our EPT handler if the guest access a page
|
||||
// outside a usable range, despite the EPT frame being present here
|
||||
//
|
||||
__stosq((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
|
||||
CpuStosQ((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
|
||||
|
||||
//
|
||||
// For each of the 512 collections of 512 2MB PML2 entries
|
||||
|
|
@ -843,7 +873,7 @@ EptLogicalProcessorInitialize(VOID)
|
|||
//
|
||||
ProcessorsCount = KeQueryActiveProcessorCount(0);
|
||||
|
||||
for (size_t i = 0; i < ProcessorsCount; i++)
|
||||
for (SIZE_T i = 0; i < ProcessorsCount; i++)
|
||||
{
|
||||
//
|
||||
// Allocate the identity mapped page table
|
||||
|
|
@ -855,7 +885,7 @@ EptLogicalProcessorInitialize(VOID)
|
|||
//
|
||||
// Try to deallocate previous pools (if any)
|
||||
//
|
||||
for (size_t j = 0; j < ProcessorsCount; j++)
|
||||
for (SIZE_T j = 0; j < ProcessorsCount; j++)
|
||||
{
|
||||
if (g_GuestState[j].EptPageTable != NULL)
|
||||
{
|
||||
|
|
@ -1083,7 +1113,7 @@ EptHandleEptViolation(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Reading guest physical address
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
|
||||
VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
|
||||
|
||||
if (EptHandlePageHookExit(VCpu, ViolationQualification, GuestPhysicalAddr))
|
||||
{
|
||||
|
|
@ -1123,7 +1153,7 @@ EptHandleMisconfiguration(VOID)
|
|||
{
|
||||
UINT64 GuestPhysicalAddr = 0;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
|
||||
VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
|
||||
|
||||
LogInfo("EPT Misconfiguration!");
|
||||
|
||||
|
|
@ -1206,7 +1236,7 @@ EptCheckAndHandleEptHookBreakpoints(VIRTUAL_MACHINE_STATE * VCpu, UINT64 GuestRi
|
|||
|
||||
if (HookedEntry->IsExecutionHook)
|
||||
{
|
||||
for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
|
||||
for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
|
||||
{
|
||||
if (HookedEntry->BreakpointAddresses[i] == GuestRip)
|
||||
{
|
||||
|
|
@ -1292,7 +1322,7 @@ EptCheckAndHandleBreakpoint(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Reading guest's RIP
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
|
||||
|
||||
//
|
||||
// Don't increment rip by default
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file Counters.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief The functions for emulating counters
|
||||
|
|
@ -26,7 +26,7 @@ CounterEmulateRdtsc(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// to solve it, in the future we solve it using tsc offsetting
|
||||
// or tsc scalling (The reason is because of that fucking patchguard :( )
|
||||
//
|
||||
UINT64 Tsc = __rdtsc();
|
||||
UINT64 Tsc = CpuReadTsc();
|
||||
PGUEST_REGS GuestRegs = VCpu->Regs;
|
||||
|
||||
GuestRegs->rax = 0x00000000ffffffff & Tsc;
|
||||
|
|
@ -43,7 +43,7 @@ VOID
|
|||
CounterEmulateRdtscp(VIRTUAL_MACHINE_STATE * VCpu)
|
||||
{
|
||||
UINT32 Aux = 0;
|
||||
UINT64 Tsc = __rdtscp(&Aux);
|
||||
UINT64 Tsc = CpuReadTscp(&Aux);
|
||||
PGUEST_REGS GuestRegs = VCpu->Regs;
|
||||
|
||||
GuestRegs->rax = 0x00000000ffffffff & Tsc;
|
||||
|
|
|
|||
155
hyperdbg/hyperhv/code/vmm/vmx/CrossVmcalls.c
Normal file
155
hyperdbg/hyperhv/code/vmm/vmx/CrossVmcalls.c
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* @file CrossVmcalls.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Routines relating to cross (standalone) VMCALLs
|
||||
* @details
|
||||
* @version 0.19
|
||||
* @date 2026-04-14
|
||||
*
|
||||
* @copyright This project is released under the GNU Public License v3.
|
||||
*
|
||||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_DEBUGCTL on the target core from VMCS
|
||||
* using VMCALL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
CrossVmcallGetDebugctlVmcallOnTargetCore()
|
||||
{
|
||||
UINT64 DebugctlValue;
|
||||
AsmVmxVmcall(VMCALL_GET_VMCS_DEBUGCTL, (UINT64)&DebugctlValue, NULL64_ZERO, NULL64_ZERO);
|
||||
return DebugctlValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_LBR_CTL on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore()
|
||||
{
|
||||
UINT64 GuestIa32LbrCtlValue;
|
||||
AsmVmxVmcall(VMCALL_GET_GUEST_IA32_LBR_CTL, (UINT64)&GuestIa32LbrCtlValue, NULL64_ZERO, NULL64_ZERO);
|
||||
return GuestIa32LbrCtlValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_DEBUGCTL on the target core from VMCS using VMCALL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetDebugctlVmcallOnTargetCore(UINT64 Value)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_VMCS_DEBUGCTL, Value, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_LBR_CTL on the target core from VMCS using VMCALL
|
||||
* @param Value
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_GUEST_IA32_LBR_CTL, Value, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of MSR_LEGACY_LBR_SELECT on the target core from VMCS using VMCALL
|
||||
* @param FilterOptions
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_MSR_LBR_SELECT, FilterOptions, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
if (Set)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_VM_ENTRY_LOAD_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_UNSET_VM_ENTRY_LOAD_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-entry controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
if (Set)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_UNSET_VM_ENTRY_LOAD_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
if (Set)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_VM_EXIT_SAVE_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_UNSET_VM_EXIT_SAVE_DEBUG_CONTROLS, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-exit controls on the target core from VMCS using VMCALL
|
||||
*
|
||||
* @param Set Set or unset
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
|
||||
{
|
||||
if (Set)
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_SET_CLEAR_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsmVmxVmcall(VMCALL_UNSET_CLEAR_GUEST_IA32_LBR_CTL, NULL64_ZERO, NULL64_ZERO, NULL64_ZERO);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file Events.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @brief Functions relating to Exception Bitmap and Event (Interrupt and Exception) Injection
|
||||
|
|
@ -128,7 +128,7 @@ EventInjectPageFaultWithoutErrorCode(UINT64 PageFaultAddress)
|
|||
//
|
||||
// Write the page-fault address
|
||||
//
|
||||
__writecr2(PageFaultAddress);
|
||||
CpuWriteCr2(PageFaultAddress);
|
||||
|
||||
//
|
||||
// Make the error code
|
||||
|
|
@ -201,7 +201,7 @@ EventInjectPageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
// Cr2 is used as the page-fault address
|
||||
//
|
||||
__writecr2(PageFaultAddress);
|
||||
CpuWriteCr2(PageFaultAddress);
|
||||
|
||||
HvSuppressRipIncrement(VCpu);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ HvAdjustControls(UINT32 Ctl, UINT32 Msr)
|
|||
{
|
||||
MSR MsrValue = {0};
|
||||
|
||||
MsrValue.Flags = __readmsr(Msr);
|
||||
MsrValue.Flags = CpuReadMsr(Msr);
|
||||
Ctl &= MsrValue.Fields.High; /* bit == 0 in high word ==> must be zero */
|
||||
Ctl |= MsrValue.Fields.Low; /* bit == 1 in low word ==> must be one */
|
||||
return Ctl;
|
||||
|
|
@ -73,7 +73,7 @@ HvHandleCpuid(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// Otherwise, issue the CPUID to the logical processor based on the indexes
|
||||
// on the VP's GPRs.
|
||||
//
|
||||
__cpuidex(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
|
||||
CpuCpuIdEx(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
|
||||
|
||||
//
|
||||
// check whether we are in transparent mode or not
|
||||
|
|
@ -158,7 +158,7 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
/*
|
||||
if (CrExitQualification->Fields.Register == 4)
|
||||
{
|
||||
__vmx_vmread(VMCS_GUEST_RSP, &GuestRsp);
|
||||
VmxVmread64P(VMCS_GUEST_RSP, &GuestRsp);
|
||||
*RegPtr = GuestRsp;
|
||||
}
|
||||
*/
|
||||
|
|
@ -229,19 +229,19 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
|
|||
{
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR0, RegPtr);
|
||||
VmxVmread64P(VMCS_GUEST_CR0, RegPtr);
|
||||
|
||||
break;
|
||||
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR3, RegPtr);
|
||||
VmxVmread64P(VMCS_GUEST_CR3, RegPtr);
|
||||
|
||||
break;
|
||||
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR4, RegPtr);
|
||||
VmxVmread64P(VMCS_GUEST_CR4, RegPtr);
|
||||
|
||||
break;
|
||||
|
||||
|
|
@ -299,10 +299,10 @@ HvResumeToNextInstruction()
|
|||
{
|
||||
UINT64 ResumeRIP = NULL64_ZERO;
|
||||
UINT64 CurrentRIP = NULL64_ZERO;
|
||||
size_t ExitInstructionLength = 0;
|
||||
SIZE_T ExitInstructionLength = 0;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &CurrentRIP);
|
||||
__vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &CurrentRIP);
|
||||
VmxVmread64P(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
|
||||
|
||||
ResumeRIP = CurrentRIP + ExitInstructionLength;
|
||||
|
||||
|
|
@ -391,12 +391,28 @@ HvSetRflagTrapFlag(BOOLEAN Set)
|
|||
/**
|
||||
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
|
||||
*
|
||||
* @param VCpu
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetLoadDebugControls(BOOLEAN Set)
|
||||
HvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
|
||||
{
|
||||
ProtectedHvSetLoadDebugControls(VCpu, Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
|
||||
*
|
||||
* @param VCpu
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetLoadGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(VCpu);
|
||||
|
||||
UINT32 VmentryControls = 0;
|
||||
|
||||
//
|
||||
|
|
@ -406,28 +422,44 @@ HvSetLoadDebugControls(BOOLEAN Set)
|
|||
|
||||
if (Set)
|
||||
{
|
||||
VmentryControls |= IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG;
|
||||
VmentryControls |= IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
VmentryControls &= ~IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG;
|
||||
VmentryControls &= ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the new value
|
||||
//
|
||||
VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
|
||||
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
|
||||
*
|
||||
* @param VCpu
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetSaveDebugControls(BOOLEAN Set)
|
||||
HvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
|
||||
{
|
||||
ProtectedHvSetSaveDebugControls(VCpu, Set);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set SAVE GUEST IA32_LBR_CTL on Vm-exit controls
|
||||
*
|
||||
* @param VCpu
|
||||
* @param Set Set or unset
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetClearGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
|
||||
{
|
||||
UNREFERENCED_PARAMETER(VCpu);
|
||||
|
||||
UINT32 VmexitControls = 0;
|
||||
|
||||
//
|
||||
|
|
@ -437,17 +469,17 @@ HvSetSaveDebugControls(BOOLEAN Set)
|
|||
|
||||
if (Set)
|
||||
{
|
||||
VmexitControls |= IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG;
|
||||
VmexitControls |= IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
VmexitControls &= ~IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG;
|
||||
VmexitControls &= ~IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the new value
|
||||
//
|
||||
VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
|
||||
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -472,22 +504,22 @@ HvRestoreRegisters()
|
|||
//
|
||||
// Restore FS Base
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_FS_BASE, &FsBase);
|
||||
__writemsr(IA32_FS_BASE, FsBase);
|
||||
VmxVmread64P(VMCS_GUEST_FS_BASE, &FsBase);
|
||||
CpuWriteMsr(IA32_FS_BASE, FsBase);
|
||||
|
||||
//
|
||||
// Restore Gs Base
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_GS_BASE, &GsBase);
|
||||
__writemsr(IA32_GS_BASE, GsBase);
|
||||
VmxVmread64P(VMCS_GUEST_GS_BASE, &GsBase);
|
||||
CpuWriteMsr(IA32_GS_BASE, GsBase);
|
||||
|
||||
//
|
||||
// Restore GDTR
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_GDTR_BASE, &GdtrBase);
|
||||
__vmx_vmread(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
|
||||
VmxVmread64P(VMCS_GUEST_GDTR_BASE, &GdtrBase);
|
||||
VmxVmread64P(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
|
||||
|
||||
AsmReloadGdtr((void *)GdtrBase, (unsigned long)GdtrLimit);
|
||||
AsmReloadGdtr((PVOID)GdtrBase, (ULONG)GdtrLimit);
|
||||
|
||||
//
|
||||
// Restore Segment Selector
|
||||
|
|
@ -504,10 +536,10 @@ HvRestoreRegisters()
|
|||
//
|
||||
// Restore IDTR
|
||||
//
|
||||
__vmx_vmread(VMCS_GUEST_IDTR_BASE, &IdtrBase);
|
||||
__vmx_vmread(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
|
||||
VmxVmread64P(VMCS_GUEST_IDTR_BASE, &IdtrBase);
|
||||
VmxVmread64P(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
|
||||
|
||||
AsmReloadIdtr((void *)IdtrBase, (unsigned long)IdtrLimit);
|
||||
AsmReloadIdtr((PVOID)IdtrBase, (ULONG)IdtrLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -860,11 +892,11 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
if (Dr7.GeneralDetect)
|
||||
{
|
||||
DR6 Dr6 = {
|
||||
.AsUInt = __readdr(6),
|
||||
.AsUInt = CpuReadDr(6),
|
||||
.BreakpointCondition = 0,
|
||||
.DebugRegisterAccessDetected = TRUE};
|
||||
|
||||
__writedr(6, Dr6.AsUInt);
|
||||
CpuWriteDr(6, Dr6.AsUInt);
|
||||
|
||||
Dr7.GeneralDetect = FALSE;
|
||||
|
||||
|
|
@ -906,22 +938,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
switch (ExitQualification.DebugRegister)
|
||||
{
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
|
||||
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
|
||||
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -932,22 +964,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
switch (ExitQualification.DebugRegister)
|
||||
{
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
|
||||
break;
|
||||
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
|
||||
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
|
||||
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1079,7 +1111,6 @@ HvSetExternalInterruptExiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
|
|||
* @brief Checks to enable and reinject previous interrupts
|
||||
*
|
||||
* @param VCpu The virtual processor's state
|
||||
* @param Set Set or unset the External Interrupt Exiting
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
|
|
@ -1152,7 +1183,7 @@ HvGetCsSelector()
|
|||
//
|
||||
UINT64 CsSel = NULL64_ZERO;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CS_SELECTOR, &CsSel);
|
||||
VmxVmread64P(VMCS_GUEST_CS_SELECTOR, &CsSel);
|
||||
|
||||
return CsSel & 0xffff;
|
||||
}
|
||||
|
|
@ -1167,7 +1198,7 @@ HvGetRflags()
|
|||
{
|
||||
UINT64 Rflags = NULL64_ZERO;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
|
||||
VmxVmread64P(VMCS_GUEST_RFLAGS, &Rflags);
|
||||
|
||||
return Rflags;
|
||||
}
|
||||
|
|
@ -1194,7 +1225,7 @@ HvGetRip()
|
|||
{
|
||||
UINT64 Rip = NULL64_ZERO;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &Rip);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &Rip);
|
||||
|
||||
return Rip;
|
||||
}
|
||||
|
|
@ -1221,7 +1252,7 @@ HvGetInterruptibilityState()
|
|||
{
|
||||
UINT64 InterruptibilityState = NULL64_ZERO;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
|
||||
VmxVmread64P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
|
||||
|
||||
return InterruptibilityState;
|
||||
}
|
||||
|
|
@ -1503,6 +1534,69 @@ HvGetDebugctl()
|
|||
return (UINT64)HighPart << 32 | LowPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the guest state of IA32_LBR_CTL
|
||||
*
|
||||
* @return UINT64
|
||||
*/
|
||||
UINT64
|
||||
HvGetGuestIa32LbrCtl()
|
||||
{
|
||||
UINT64 GuestIa32LbrCtl;
|
||||
|
||||
VmxVmread64P(VMCS_GUEST_LBR_CTL, &GuestIa32LbrCtl);
|
||||
|
||||
return GuestIa32LbrCtl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get and store the guest state of IA32_DEBUGCTL
|
||||
* @details mainly used from the VMCALL handler
|
||||
*
|
||||
* @param StoreDebugctl
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvGetAndStoreDebugctl(UINT64 * StoreDebugctl)
|
||||
{
|
||||
UINT64 DebugctlValue;
|
||||
|
||||
//
|
||||
// Read DEBUGCTL from VMCS
|
||||
//
|
||||
DebugctlValue = HvGetDebugctl();
|
||||
|
||||
//
|
||||
// Store the DEBUGCTL
|
||||
//
|
||||
*StoreDebugctl = DebugctlValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get and store the guest state of IA32_LBR_CTL
|
||||
* @details mainly used from the VMCALL handler
|
||||
*
|
||||
* @param StoreGuestIa32Lbr
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvGetAndStoreGuestIa32LbrCtl(UINT64 * StoreGuestIa32Lbr)
|
||||
{
|
||||
UINT64 GuestIa32LbrCtl;
|
||||
|
||||
//
|
||||
// Read IA32_LBR_CTL from VMCS
|
||||
//
|
||||
GuestIa32LbrCtl = HvGetGuestIa32LbrCtl();
|
||||
|
||||
//
|
||||
// Store the IA32_LBR_CTL
|
||||
//
|
||||
*StoreGuestIa32Lbr = GuestIa32LbrCtl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_DEBUGCTL
|
||||
* @param Value The new state
|
||||
|
|
@ -1512,8 +1606,141 @@ HvGetDebugctl()
|
|||
VOID
|
||||
HvSetDebugctl(UINT64 Value)
|
||||
{
|
||||
VmxVmwrite64(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
|
||||
VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
|
||||
VmxVmwrite32(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
|
||||
VmxVmwrite32(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of IA32_LBR_CTL
|
||||
* @param Value The new state
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetGuestIa32LbrCtl(UINT64 Value)
|
||||
{
|
||||
VmxVmwrite64(VMCS_GUEST_LBR_CTL, Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LBR selector
|
||||
* @details If VMM is active, this should be done in vmx-root, otherwise, it doesn't work
|
||||
* @param FilterOptions The value to write on MSR_LEGACY_LBR_SELECT
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetLbrSelect(UINT64 FilterOptions)
|
||||
{
|
||||
CpuWriteMsr(MSR_LEGACY_LBR_SELECT, FilterOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if CPU support save and load debug controls on exit and load entries
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HvCheckCpuSupportForSaveAndLoadDebugControls()
|
||||
{
|
||||
IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
|
||||
|
||||
//
|
||||
// Reading IA32_VMX_BASIC_MSR
|
||||
//
|
||||
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
|
||||
|
||||
//
|
||||
// Read 1-settings of save debug controls (exit controls)
|
||||
//
|
||||
UINT32 ExitCtls = HvAdjustControls(
|
||||
IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG,
|
||||
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
|
||||
|
||||
//
|
||||
// Read 1-settings of load debug controls (entry controls)
|
||||
//
|
||||
UINT32 EntryCtls = HvAdjustControls(
|
||||
IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG,
|
||||
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
|
||||
|
||||
//
|
||||
// Check if entry and exit controls are supported on this system
|
||||
//
|
||||
if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
|
||||
{
|
||||
//
|
||||
// Supported
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Not supported
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on entry and exit
|
||||
*
|
||||
* @return BOOLEAN
|
||||
*/
|
||||
BOOLEAN
|
||||
HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
|
||||
{
|
||||
IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
|
||||
|
||||
//
|
||||
// Reading IA32_VMX_BASIC_MSR
|
||||
//
|
||||
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
|
||||
|
||||
//
|
||||
// Read 1-settings of save debug controls (exit controls)
|
||||
//
|
||||
UINT32 ExitCtls = HvAdjustControls(
|
||||
IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG,
|
||||
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
|
||||
|
||||
//
|
||||
// Read 1-settings of load debug controls (entry controls)
|
||||
//
|
||||
UINT32 EntryCtls = HvAdjustControls(
|
||||
IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG,
|
||||
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
|
||||
|
||||
//
|
||||
// Check if entry and exit controls are supported on this system
|
||||
//
|
||||
if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
|
||||
{
|
||||
//
|
||||
// Supported
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Not supported
|
||||
//
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the guest state of DR7
|
||||
* @param Value The new value for DR7
|
||||
*
|
||||
* @return VOID
|
||||
*/
|
||||
VOID
|
||||
HvSetDebugReg7(UINT64 Value)
|
||||
{
|
||||
VmxVmwrite64(VMCS_GUEST_DR7, Value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
|
|||
//
|
||||
// Since it's not in VMX Root, we can directly read the IDTR register
|
||||
//
|
||||
__sidt(&IdtrReg);
|
||||
CpuSidt(&IdtrReg);
|
||||
|
||||
//
|
||||
// Get the IDT base address
|
||||
|
|
@ -55,9 +55,9 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
|
|||
//
|
||||
for (UINT32 i = 0; i < MAX_NUMBER_OF_IDT_ENTRIES; i++)
|
||||
{
|
||||
IdtQueryRequest->IdtEntry[i] = (UINT64)((unsigned long long)IdtEntries[i].HighestPart << 32) |
|
||||
((unsigned long long)IdtEntries[i].HighPart << 16) |
|
||||
(unsigned long long)IdtEntries[i].LowPart;
|
||||
IdtQueryRequest->IdtEntry[i] = (UINT64)((UINT64)IdtEntries[i].HighestPart << 32) |
|
||||
((UINT64)IdtEntries[i].HighPart << 16) |
|
||||
(UINT64)IdtEntries[i].LowPart;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
|
|||
HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
|
||||
|
||||
/*
|
||||
for (size_t i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
|
||||
for (SIZE_T i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
|
||||
{
|
||||
SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 CurrentEntry = WindowsIdt[i];
|
||||
|
||||
|
|
@ -217,7 +217,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
|
|||
if (!VmxBroadcastHandleNmiCallback((PVOID)IntrTrapFrame, FALSE))
|
||||
{
|
||||
//
|
||||
// We cannot just use the NMI Window Exiting here becasue
|
||||
// We cannot just use the NMI Window Exiting here because
|
||||
// in certain scenarios, VMRESUME with Error 0x7 will happen
|
||||
// Which means that the layout of the VMCS is wrong
|
||||
//
|
||||
|
|
@ -258,7 +258,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
|
|||
//
|
||||
// host page-fault
|
||||
//
|
||||
PageFaultCr2 = __readcr2();
|
||||
PageFaultCr2 = CpuReadCr2();
|
||||
|
||||
LogInfo("Page-fault received, rip: %llx, rsp: %llx, error: %llx, CR2: %llx",
|
||||
IntrTrapFrame->rip,
|
||||
|
|
@ -309,7 +309,7 @@ IdtEmulationHandlePageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
//
|
||||
// Read the page-fault address
|
||||
//
|
||||
__vmx_vmread(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
|
||||
VmxVmread64P(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
|
||||
|
||||
// LogInfo("#PF Fault = %016llx, Page Fault Code = 0x%x | %s%s%s%s",
|
||||
// PageFaultAddress,
|
||||
|
|
@ -356,7 +356,8 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
UINT64 GuestRip = NULL64_ZERO;
|
||||
BYTE TargetMem = NULL_ZERO;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
|
||||
|
||||
MemoryMapperReadMemorySafe(GuestRip, &TargetMem, sizeof(BYTE));
|
||||
|
||||
if (!EptCheckAndHandleBreakpoint(VCpu) || TargetMem == 0xcc)
|
||||
|
|
@ -434,7 +435,7 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
|
|||
|
||||
if (VCpu->EnableExternalInterruptsOnContinue ||
|
||||
VCpu->EnableExternalInterruptsOnContinueMtf ||
|
||||
VCpu->RegisterBreakOnMtf)
|
||||
VCpu->InstrumentationStepInMtf)
|
||||
{
|
||||
//
|
||||
// Ignore the nmi
|
||||
|
|
@ -480,7 +481,7 @@ IdtEmulationInjectInterruptWhenInterruptWindowIsOpen(_Inout_ VIRTUAL_MACHINE_STA
|
|||
// We can't inject interrupt because the guest's state is not interruptible
|
||||
// we have to queue it an re-inject it when the interrupt window is opened !
|
||||
//
|
||||
for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
|
||||
for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
|
||||
{
|
||||
//
|
||||
// Find an empty space
|
||||
|
|
@ -676,7 +677,7 @@ IdtEmulationHandleInterruptWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
if (!InjectPageFault)
|
||||
{
|
||||
for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
|
||||
for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
|
||||
{
|
||||
//
|
||||
// Find an empty space
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ IoHandleIoVmExits(VIRTUAL_MACHINE_STATE * VCpu, VMX_EXIT_QUALIFICATION_IO_INSTRU
|
|||
|
||||
union
|
||||
{
|
||||
unsigned char * AsBytePtr;
|
||||
unsigned short * AsWordPtr;
|
||||
unsigned long * AsDwordPtr;
|
||||
UCHAR * AsBytePtr;
|
||||
USHORT * AsWordPtr;
|
||||
ULONG * AsDwordPtr;
|
||||
|
||||
void * AsPtr;
|
||||
UINT64 AsUint64;
|
||||
PVOID AsPtr;
|
||||
UINT64 AsUInt64;
|
||||
|
||||
} PortValue;
|
||||
|
||||
|
|
@ -215,11 +215,11 @@ IoHandleSetIoBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Port)
|
|||
{
|
||||
if (Port <= 0x7FFF)
|
||||
{
|
||||
SetBit(Port, (unsigned long *)VCpu->IoBitmapVirtualAddressA);
|
||||
SetBit(Port, (ULONG *)VCpu->IoBitmapVirtualAddressA);
|
||||
}
|
||||
else if ((0x8000 <= Port) && (Port <= 0xFFFF))
|
||||
{
|
||||
SetBit(Port - 0x8000, (unsigned long *)VCpu->IoBitmapVirtualAddressB);
|
||||
SetBit(Port - 0x8000, (ULONG *)VCpu->IoBitmapVirtualAddressB);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -245,8 +245,8 @@ IoHandlePerformIoBitmapChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Port)
|
|||
//
|
||||
// Means all the bitmaps should be put to 1
|
||||
//
|
||||
memset((void *)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
|
||||
memset((void *)VCpu->IoBitmapVirtualAddressB, 0xFF, PAGE_SIZE);
|
||||
memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0xFF, PAGE_SIZE);
|
||||
memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0xFF, PAGE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -270,6 +270,6 @@ IoHandlePerformIoBitmapReset(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Means all the bitmaps should be put to 0
|
||||
//
|
||||
memset((void *)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
|
||||
memset((void *)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
|
||||
memset((PVOID)VCpu->IoBitmapVirtualAddressA, 0x0, PAGE_SIZE);
|
||||
memset((PVOID)VCpu->IoBitmapVirtualAddressB, 0x0, PAGE_SIZE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/**
|
||||
* @file ManageRegs.c
|
||||
* @author Sina Karvandi (sina@hyperdbg.org)
|
||||
* @author Alee Amini (alee@hyperdbg.org)
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
VOID
|
||||
SetGuestCsSel(PVMX_SEGMENT_SELECTOR Cs)
|
||||
{
|
||||
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
|
||||
VmxVmwrite16(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -34,10 +34,10 @@ SetGuestCsSel(PVMX_SEGMENT_SELECTOR Cs)
|
|||
VOID
|
||||
SetGuestCs(PVMX_SEGMENT_SELECTOR Cs)
|
||||
{
|
||||
__vmx_vmwrite(VMCS_GUEST_CS_BASE, Cs->Base);
|
||||
__vmx_vmwrite(VMCS_GUEST_CS_LIMIT, Cs->Limit);
|
||||
__vmx_vmwrite(VMCS_GUEST_CS_ACCESS_RIGHTS, Cs->Attributes.AsUInt);
|
||||
__vmx_vmwrite(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
|
||||
VmxVmwrite64(VMCS_GUEST_CS_BASE, Cs->Base);
|
||||
VmxVmwrite32(VMCS_GUEST_CS_LIMIT, Cs->Limit);
|
||||
VmxVmwrite32(VMCS_GUEST_CS_ACCESS_RIGHTS, Cs->Attributes.AsUInt);
|
||||
VmxVmwrite16(VMCS_GUEST_CS_SELECTOR, Cs->Selector);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,7 +50,7 @@ GetGuestCs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Cs;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CS_BASE, &Cs.Base);
|
||||
VmxVmread64P(VMCS_GUEST_CS_BASE, &Cs.Base);
|
||||
VmxVmread32P(VMCS_GUEST_CS_LIMIT, &Cs.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_CS_ACCESS_RIGHTS, &Cs.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_CS_SELECTOR, &Cs.Selector);
|
||||
|
|
@ -67,7 +67,7 @@ GetGuestCs()
|
|||
VOID
|
||||
SetGuestSsSel(PVMX_SEGMENT_SELECTOR Ss)
|
||||
{
|
||||
__vmx_vmwrite(VMCS_GUEST_SS_SELECTOR, Ss->Selector);
|
||||
VmxVmwrite16(VMCS_GUEST_SS_SELECTOR, Ss->Selector);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -95,7 +95,7 @@ GetGuestSs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Ss;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_SS_BASE, &Ss.Base);
|
||||
VmxVmread64P(VMCS_GUEST_SS_BASE, &Ss.Base);
|
||||
VmxVmread32P(VMCS_GUEST_SS_LIMIT, &Ss.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_SS_ACCESS_RIGHTS, &Ss.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_SS_SELECTOR, &Ss.Selector);
|
||||
|
|
@ -140,7 +140,7 @@ GetGuestDs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Ds;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_DS_BASE, &Ds.Base);
|
||||
VmxVmread64P(VMCS_GUEST_DS_BASE, &Ds.Base);
|
||||
VmxVmread32P(VMCS_GUEST_DS_LIMIT, &Ds.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_DS_ACCESS_RIGHTS, &Ds.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_DS_SELECTOR, &Ds.Selector);
|
||||
|
|
@ -185,7 +185,7 @@ GetGuestFs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Fs;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_FS_BASE, &Fs.Base);
|
||||
VmxVmread64P(VMCS_GUEST_FS_BASE, &Fs.Base);
|
||||
VmxVmread32P(VMCS_GUEST_FS_LIMIT, &Fs.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_FS_ACCESS_RIGHTS, &Fs.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_FS_SELECTOR, &Fs.Selector);
|
||||
|
|
@ -230,7 +230,7 @@ GetGuestGs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Gs;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_GS_BASE, &Gs.Base);
|
||||
VmxVmread64P(VMCS_GUEST_GS_BASE, &Gs.Base);
|
||||
VmxVmread32P(VMCS_GUEST_GS_LIMIT, &Gs.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_GS_ACCESS_RIGHTS, &Gs.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_GS_SELECTOR, &Gs.Selector);
|
||||
|
|
@ -275,7 +275,7 @@ GetGuestEs()
|
|||
{
|
||||
VMX_SEGMENT_SELECTOR Es;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_ES_BASE, &Es.Base);
|
||||
VmxVmread64P(VMCS_GUEST_ES_BASE, &Es.Base);
|
||||
VmxVmread32P(VMCS_GUEST_ES_LIMIT, &Es.Limit);
|
||||
VmxVmread32P(VMCS_GUEST_ES_ACCESS_RIGHTS, &Es.Attributes.AsUInt);
|
||||
VmxVmread16P(VMCS_GUEST_ES_SELECTOR, &Es.Selector);
|
||||
|
|
@ -305,7 +305,7 @@ GetGuestIdtr()
|
|||
{
|
||||
UINT64 Idtr;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_IDTR_BASE, &Idtr);
|
||||
VmxVmread64P(VMCS_GUEST_IDTR_BASE, &Idtr);
|
||||
|
||||
return Idtr;
|
||||
}
|
||||
|
|
@ -332,7 +332,7 @@ GetGuestLdtr()
|
|||
{
|
||||
UINT64 Ldtr;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_LDTR_BASE, &Ldtr);
|
||||
VmxVmread64P(VMCS_GUEST_LDTR_BASE, &Ldtr);
|
||||
|
||||
return Ldtr;
|
||||
}
|
||||
|
|
@ -359,7 +359,7 @@ GetGuestGdtr()
|
|||
{
|
||||
UINT64 Gdtr;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_GDTR_BASE, &Gdtr);
|
||||
VmxVmread64P(VMCS_GUEST_GDTR_BASE, &Gdtr);
|
||||
|
||||
return Gdtr;
|
||||
}
|
||||
|
|
@ -384,7 +384,7 @@ GetGuestTr()
|
|||
{
|
||||
UINT64 Tr;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_TR_BASE, &Tr);
|
||||
VmxVmread64P(VMCS_GUEST_TR_BASE, &Tr);
|
||||
|
||||
return Tr;
|
||||
}
|
||||
|
|
@ -409,7 +409,9 @@ UINT64
|
|||
GetGuestRFlags()
|
||||
{
|
||||
UINT64 RFlags;
|
||||
__vmx_vmread(VMCS_GUEST_RFLAGS, &RFlags);
|
||||
|
||||
VmxVmread64P(VMCS_GUEST_RFLAGS, &RFlags);
|
||||
|
||||
return RFlags;
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +449,8 @@ GetGuestRIP()
|
|||
{
|
||||
UINT64 RIP;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_RIP, &RIP);
|
||||
VmxVmread64P(VMCS_GUEST_RIP, &RIP);
|
||||
|
||||
return RIP;
|
||||
}
|
||||
|
||||
|
|
@ -461,7 +464,8 @@ GetGuestCr0()
|
|||
{
|
||||
UINT64 Cr0;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR0, &Cr0);
|
||||
VmxVmread64P(VMCS_GUEST_CR0, &Cr0);
|
||||
|
||||
return Cr0;
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +479,7 @@ GetGuestCr2()
|
|||
{
|
||||
UINT64 Cr2;
|
||||
|
||||
Cr2 = __readcr2();
|
||||
Cr2 = CpuReadCr2();
|
||||
return Cr2;
|
||||
}
|
||||
|
||||
|
|
@ -489,7 +493,8 @@ GetGuestCr3()
|
|||
{
|
||||
UINT64 Cr3;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR3, &Cr3);
|
||||
VmxVmread64P(VMCS_GUEST_CR3, &Cr3);
|
||||
|
||||
return Cr3;
|
||||
}
|
||||
|
||||
|
|
@ -503,7 +508,8 @@ GetGuestCr4()
|
|||
{
|
||||
UINT64 Cr4;
|
||||
|
||||
__vmx_vmread(VMCS_GUEST_CR4, &Cr4);
|
||||
VmxVmread64P(VMCS_GUEST_CR4, &Cr4);
|
||||
|
||||
return Cr4;
|
||||
}
|
||||
|
||||
|
|
@ -517,7 +523,7 @@ GetGuestCr8()
|
|||
{
|
||||
UINT64 Cr8;
|
||||
|
||||
Cr8 = __readcr8();
|
||||
Cr8 = CpuReadCr8();
|
||||
return Cr8;
|
||||
}
|
||||
|
||||
|
|
@ -542,7 +548,7 @@ SetGuestCr0(UINT64 Cr0)
|
|||
VOID
|
||||
SetGuestCr2(UINT64 Cr2)
|
||||
{
|
||||
__writecr2(Cr2);
|
||||
CpuWriteCr2(Cr2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -578,7 +584,7 @@ SetGuestCr4(UINT64 Cr4)
|
|||
VOID
|
||||
SetGuestCr8(UINT64 Cr8)
|
||||
{
|
||||
__writecr8(Cr8);
|
||||
CpuWriteCr8(Cr8);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -590,7 +596,7 @@ SetGuestCr8(UINT64 Cr8)
|
|||
VOID
|
||||
SetGuestDr0(UINT64 value)
|
||||
{
|
||||
__writedr(0, value);
|
||||
CpuWriteDr(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -602,7 +608,7 @@ SetGuestDr0(UINT64 value)
|
|||
VOID
|
||||
SetGuestDr1(UINT64 value)
|
||||
{
|
||||
__writedr(1, value);
|
||||
CpuWriteDr(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -614,7 +620,7 @@ SetGuestDr1(UINT64 value)
|
|||
VOID
|
||||
SetGuestDr2(UINT64 value)
|
||||
{
|
||||
__writedr(2, value);
|
||||
CpuWriteDr(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -626,7 +632,7 @@ SetGuestDr2(UINT64 value)
|
|||
VOID
|
||||
SetGuestDr3(UINT64 value)
|
||||
{
|
||||
__writedr(3, value);
|
||||
CpuWriteDr(3, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -638,7 +644,7 @@ SetGuestDr3(UINT64 value)
|
|||
VOID
|
||||
SetGuestDr6(UINT64 value)
|
||||
{
|
||||
__writedr(6, value);
|
||||
CpuWriteDr(6, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -650,7 +656,7 @@ SetGuestDr6(UINT64 value)
|
|||
VOID
|
||||
SetGuestDr7(UINT64 value)
|
||||
{
|
||||
__writedr(7, value);
|
||||
CpuWriteDr(7, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -662,7 +668,7 @@ UINT64
|
|||
GetGuestDr0()
|
||||
{
|
||||
UINT64 Dr0 = 0;
|
||||
Dr0 = __readdr(0);
|
||||
Dr0 = CpuReadDr(0);
|
||||
return Dr0;
|
||||
}
|
||||
|
||||
|
|
@ -675,7 +681,7 @@ UINT64
|
|||
GetGuestDr1()
|
||||
{
|
||||
UINT64 Dr1 = 0;
|
||||
Dr1 = __readdr(1);
|
||||
Dr1 = CpuReadDr(1);
|
||||
return Dr1;
|
||||
}
|
||||
|
||||
|
|
@ -688,7 +694,7 @@ UINT64
|
|||
GetGuestDr2()
|
||||
{
|
||||
UINT64 Dr2 = 0;
|
||||
Dr2 = __readdr(2);
|
||||
Dr2 = CpuReadDr(2);
|
||||
return Dr2;
|
||||
}
|
||||
|
||||
|
|
@ -701,7 +707,7 @@ UINT64
|
|||
GetGuestDr3()
|
||||
{
|
||||
UINT64 Dr3 = 0;
|
||||
Dr3 = __readdr(3);
|
||||
Dr3 = CpuReadDr(3);
|
||||
return Dr3;
|
||||
}
|
||||
|
||||
|
|
@ -714,7 +720,7 @@ UINT64
|
|||
GetGuestDr6()
|
||||
{
|
||||
UINT64 Dr6 = 0;
|
||||
Dr6 = __readdr(6);
|
||||
Dr6 = CpuReadDr(6);
|
||||
return Dr6;
|
||||
}
|
||||
|
||||
|
|
@ -727,6 +733,6 @@ UINT64
|
|||
GetGuestDr7()
|
||||
{
|
||||
UINT64 Dr7 = 0;
|
||||
Dr7 = __readdr(7);
|
||||
Dr7 = CpuReadDr(7);
|
||||
return Dr7;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,49 @@
|
|||
*/
|
||||
#include "pch.h"
|
||||
|
||||
/**
|
||||
* @brief Checks whether an MSR belongs to the Hyper-V synthetic MSR set
|
||||
* @details The ranges and individual registers are defined by Hyper-V TLFS
|
||||
* synthetic MSRs and mirrored in HypervTlfs.h.
|
||||
*
|
||||
* @param TargetMsr The target MSR
|
||||
* @return BOOLEAN Returns TRUE if the MSR should be forwarded to the
|
||||
* top-level Hyper-V compatible hypervisor
|
||||
*/
|
||||
BOOLEAN
|
||||
MsrHandleIsHypervSyntheticMsr(_In_ UINT32 TargetMsr)
|
||||
{
|
||||
switch (TargetMsr)
|
||||
{
|
||||
case HV_X64_MSR_GUEST_OS_ID:
|
||||
case HV_X64_MSR_HYPERCALL:
|
||||
case HV_X64_MSR_VP_INDEX:
|
||||
case HV_X64_MSR_RESET:
|
||||
case HV_X64_MSR_VP_RUNTIME:
|
||||
case HV_X64_MSR_TIME_REF_COUNT:
|
||||
case HV_X64_MSR_REFERENCE_TSC:
|
||||
case HV_X64_MSR_TSC_FREQUENCY:
|
||||
case HV_X64_MSR_APIC_FREQUENCY:
|
||||
case HV_X64_MSR_NPIEP_CONFIG:
|
||||
case HV_X64_MSR_GUEST_IDLE:
|
||||
case HV_X64_MSR_REENLIGHTENMENT_CONTROL:
|
||||
case HV_X64_MSR_TSC_EMULATION_CONTROL:
|
||||
case HV_X64_MSR_TSC_EMULATION_STATUS:
|
||||
case HV_X64_MSR_STIME_UNHALTED_TIMER_CONFIG:
|
||||
case HV_X64_MSR_STIME_UNHALTED_TIMER_COUNT:
|
||||
case HV_X64_MSR_NESTED_VP_INDEX:
|
||||
return TRUE;
|
||||
default:
|
||||
return (TargetMsr >= HV_X64_MSR_EOI && TargetMsr <= HV_X64_MSR_TPR) ||
|
||||
(TargetMsr >= HV_X64_MSR_SCONTROL && TargetMsr <= HV_X64_MSR_EOM) ||
|
||||
(TargetMsr >= HV_X64_MSR_SINT0 && TargetMsr <= HV_X64_MSR_SINT15) ||
|
||||
(TargetMsr >= HV_X64_MSR_STIMER0_CONFIG && TargetMsr <= HV_X64_MSR_STIMER3_COUNT) ||
|
||||
(TargetMsr >= HV_X64_MSR_CRASH_P0 && TargetMsr <= HV_X64_MSR_CRASH_CTL) ||
|
||||
(TargetMsr >= HV_X64_MSR_NESTED_SCONTROL && TargetMsr <= HV_X64_MSR_NESTED_EOM) ||
|
||||
(TargetMsr >= HV_X64_MSR_NESTED_SINT0 && TargetMsr <= HV_X64_MSR_NESTED_SINT15);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles in the cases when RDMSR causes a vm-exit
|
||||
*
|
||||
|
|
@ -54,6 +97,19 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// TargetMsr,
|
||||
// VCpu->LastVmexitRip);
|
||||
|
||||
//
|
||||
// Checking whether it is a synthetic MSR for Hyper-V
|
||||
//
|
||||
if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
|
||||
{
|
||||
Msr.Flags = CpuReadMsr(TargetMsr);
|
||||
|
||||
GuestRegs->rax = Msr.Fields.Low;
|
||||
GuestRegs->rdx = Msr.Fields.High;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for sanity of MSR if they're valid or they're for reserved range for WRMSR and RDMSR
|
||||
//
|
||||
|
|
@ -114,7 +170,7 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Check whether the MSR should cause #GP or not
|
||||
//
|
||||
if (TargetMsr <= 0xfff && TestBit(TargetMsr, (unsigned long *)g_MsrBitmapInvalidMsrs) != NULL64_ZERO)
|
||||
if (TargetMsr <= 0xfff && TestBit(TargetMsr, (ULONG *)g_MsrBitmapInvalidMsrs) != NULL64_ZERO)
|
||||
{
|
||||
//
|
||||
// Invalid MSR between 0x0 to 0xfff
|
||||
|
|
@ -134,7 +190,7 @@ MsrHandleRdmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Msr is valid
|
||||
//
|
||||
Msr.Flags = __readmsr(TargetMsr);
|
||||
Msr.Flags = CpuReadMsr(TargetMsr);
|
||||
|
||||
//
|
||||
// Check if it's EFER MSR then we show a false SCE state
|
||||
|
|
@ -204,6 +260,15 @@ MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
// GuestRegs->rdx,
|
||||
// VCpu->LastVmexitRip);
|
||||
|
||||
//
|
||||
// Checking whether it is a synthetic MSR for Hyper-V
|
||||
//
|
||||
if (g_IsTopLevelHypervisorHyperV && MsrHandleIsHypervSyntheticMsr(TargetMsr))
|
||||
{
|
||||
CpuWriteMsr(TargetMsr, Msr.Flags);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Check for sanity of MSR if they're valid or they're for reserved range for WRMSR and RDMSR
|
||||
//
|
||||
|
|
@ -278,7 +343,7 @@ MsrHandleWrmsrVmexit(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Perform the WRMSR
|
||||
//
|
||||
__writemsr((unsigned long)GuestRegs->rcx, Msr.Flags);
|
||||
CpuWriteMsr((ULONG)GuestRegs->rcx, Msr.Flags);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -317,22 +382,22 @@ MsrHandleSetMsrBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Msr, BOOLEAN ReadDete
|
|||
{
|
||||
if (ReadDetection)
|
||||
{
|
||||
SetBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
|
||||
SetBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress);
|
||||
}
|
||||
if (WriteDetection)
|
||||
{
|
||||
SetBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress + 2048);
|
||||
SetBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress + 2048);
|
||||
}
|
||||
}
|
||||
else if ((0xC0000000 <= Msr) && (Msr <= 0xC0001FFF))
|
||||
{
|
||||
if (ReadDetection)
|
||||
{
|
||||
SetBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
SetBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
}
|
||||
if (WriteDetection)
|
||||
{
|
||||
SetBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
SetBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -366,22 +431,22 @@ MsrHandleUnSetMsrBitmap(VIRTUAL_MACHINE_STATE * VCpu, UINT32 Msr, BOOLEAN ReadDe
|
|||
{
|
||||
if (ReadDetection)
|
||||
{
|
||||
ClearBit(Msr, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
|
||||
ClearBit(Msr, (ULONG *)VCpu->MsrBitmapVirtualAddress);
|
||||
}
|
||||
if (WriteDetection)
|
||||
{
|
||||
ClearBit(Msr, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(Msr, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
}
|
||||
}
|
||||
else if ((0xC0000000 <= Msr) && (Msr <= 0xC0001FFF))
|
||||
{
|
||||
if (ReadDetection)
|
||||
{
|
||||
ClearBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
ClearBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
}
|
||||
if (WriteDetection)
|
||||
{
|
||||
ClearBit(Msr - 0xC0000000, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
ClearBit(Msr - 0xC0000000, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -404,13 +469,13 @@ MsrHandleFilterMsrReadBitmap(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Ignore IA32_KERNEL_GSBASE (0xC0000102)
|
||||
//
|
||||
ClearBit(0x102, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
ClearBit(0x102, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 1024));
|
||||
|
||||
//
|
||||
// Ignore IA32_MPERF (0x000000e7), and IA32_APERF (0x000000e8)
|
||||
//
|
||||
ClearBit(0xe7, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
|
||||
ClearBit(0xe8, (unsigned long *)VCpu->MsrBitmapVirtualAddress);
|
||||
ClearBit(0xe7, (ULONG *)VCpu->MsrBitmapVirtualAddress);
|
||||
ClearBit(0xe8, (ULONG *)VCpu->MsrBitmapVirtualAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -426,19 +491,19 @@ MsrHandleFilterMsrWriteBitmap(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Ignore IA32_KERNEL_GSBASE (0xC0000102)
|
||||
//
|
||||
ClearBit(0x102, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
ClearBit(0x102, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 3072));
|
||||
|
||||
//
|
||||
// Ignore IA32_MPERF (0x000000e7), and IA32_APERF (0x000000e8)
|
||||
//
|
||||
ClearBit(0xe7, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0xe8, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0xe7, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0xe8, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
|
||||
//
|
||||
// Ignore IA32_SPEC_CTRL (0x00000048), and IA32_PRED_CMD (0x00000049)
|
||||
//
|
||||
ClearBit(0x48, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0x49, (unsigned long *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0x48, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
ClearBit(0x49, (ULONG *)(VCpu->MsrBitmapVirtualAddress + 2048));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -457,7 +522,7 @@ MsrHandlePerformMsrBitmapReadChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 MsrMask
|
|||
//
|
||||
// Means all the bitmaps should be put to 1
|
||||
//
|
||||
memset((void *)VCpu->MsrBitmapVirtualAddress, 0xff, 2048);
|
||||
memset((PVOID)VCpu->MsrBitmapVirtualAddress, 0xff, 2048);
|
||||
|
||||
//
|
||||
// Filter MSR Bitmap for special MSRs
|
||||
|
|
@ -486,7 +551,7 @@ MsrHandlePerformMsrBitmapReadReset(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Means all the bitmaps should be put to 0
|
||||
//
|
||||
memset((void *)VCpu->MsrBitmapVirtualAddress, 0x0, 2048);
|
||||
memset((PVOID)VCpu->MsrBitmapVirtualAddress, 0x0, 2048);
|
||||
}
|
||||
/**
|
||||
* @brief Change MSR Bitmap for write
|
||||
|
|
@ -504,7 +569,7 @@ MsrHandlePerformMsrBitmapWriteChange(VIRTUAL_MACHINE_STATE * VCpu, UINT32 MsrMas
|
|||
//
|
||||
// Means all the bitmaps should be put to 1
|
||||
//
|
||||
memset((void *)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0xff, 2048);
|
||||
memset((PVOID)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0xff, 2048);
|
||||
|
||||
//
|
||||
// Filter MSR Bitmap for special MSRs
|
||||
|
|
@ -533,5 +598,5 @@ MsrHandlePerformMsrBitmapWriteReset(VIRTUAL_MACHINE_STATE * VCpu)
|
|||
//
|
||||
// Means all the bitmaps should be put to 0
|
||||
//
|
||||
memset((void *)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0x0, 2048);
|
||||
memset((PVOID)((UINT64)VCpu->MsrBitmapVirtualAddress + 2048), 0x0, 2048);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue