Compare commits

...

404 commits

Author SHA1 Message Date
Sina Karvandi
bf974ffcc2 v0.21
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Merge pull request #634 from HyperDbg/dev
2026-07-05 15:41:02 +02:00
sina
a90513c71d update changelog for v0.21 release 2026-07-05 15:38:03 +02:00
Sina Karvandi
27838bf4e0
Merge pull request #633 from HyperDbg/pt
Pt
2026-07-05 15:25:35 +02:00
sina
9f113278ee add comment for run and trace
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-07-03 18:23:39 +02:00
sina
5739d0ee4c add PT thread helper 2026-07-03 17:26:01 +02:00
Sina Karvandi
ace4b331e7
Merge pull request #632 from HyperDbg/pt
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Pt
2026-07-02 22:00:48 +02:00
sina
ee01458bc4 Organized header files for the libhyperdbg project 2026-07-02 22:00:05 +02:00
sina
16aebb0c5d remove dependency on module details over global variables 2026-07-02 20:40:41 +02:00
sina
43cea334c2 add core and path interpretation of PT 2026-07-02 18:14:47 +02:00
Sina Karvandi
561ce0d559
Merge pull request #631 from HyperDbg/pt
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
Pt
2026-07-02 00:02:18 +02:00
sina
5bccbff58b fix IPT kernel structure based on the new model
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-07-01 19:44:15 +02:00
sina
72a8aa325f add user mode PT parameter parser 2026-06-30 20:30:25 +02:00
sina
2b0cc18899 Fix concatenation error for hyperkd string on the hypertrace project
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-06-29 18:35:14 +02:00
sina
2b818a5116 fix load all command access denied error
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-29 01:32:51 +02:00
sina
19e47c804f check if any module is loaded or not 2026-06-29 00:56:09 +02:00
sina
b537e36696 add hyperperf to version changer to fix CI CD and update changelog
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
2026-06-24 18:48:56 +02:00
Sina Karvandi
e7cef36819
Merge pull request #629 from jtaw5649/fix/pool-manager-uninit-list-corruption
Fix pool manager uninit list corruption
2026-06-24 18:46:15 +02:00
jtaw5649
a0973894e8 fix: avoid pool list cursor use after free 2026-06-24 16:45:25 +01:00
sina
edf9f269d4 refactor Intel PT DPC broadcasting routines
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-23 15:02:01 +02:00
sina
c17ebc09c4 add HyperPerf project structures
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-22 16:19:49 +02:00
sina
7dfe5be985 change version to v0.21
Some checks are pending
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-21 15:02:56 +02:00
Sina Karvandi
4e086328ee
v0.20-beta
Some checks failed
vs2026-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2026-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2026-ci / Deploy release (push) Has been cancelled
Merge pull request #628 from HyperDbg/dev
2026-06-21 14:31:43 +02:00
sina
aa18675760 update changelog and fix minor issues 2026-06-21 14:22:33 +02:00
Sina Karvandi
4bbb62d6fa
Merge pull request #627 from HyperDbg/linux
Linux guide and new progress
2026-06-21 13:23:43 +02:00
sina
5a0fad4901 add WDK and SDK NuGet packages and Fix CI/CD
Some checks are pending
vs2026-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2026-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2026-ci / Deploy release (push) Blocked by required conditions
2026-06-21 03:02:49 +02:00
maxraulea
3a8d8ab2d1 Add guidelines for contribution 2026-06-20 09:48:19 +02:00
maxraulea
83ae005c70 Added compatibility 2026-06-20 09:29:45 +02:00
maxraulea
81b16de62b added files for platform API 2026-06-20 09:28:37 +02:00
maxraulea
2d3941a43e signal handler platform independent API 2026-06-20 09:28:37 +02:00
sina
240feadc0c check for hyper-v as the top level hypervisor 2026-06-19 20:16:50 +02:00
Sina Karvandi
be59d1c9c2
Merge pull request #625 from Idov31/dev
Added VPID checking
2026-06-19 19:35:50 +02:00
Sina Karvandi
01106c82e0
Merge pull request #626 from HyperDbg/vs2026
Move to VS2026
2026-06-19 18:46:41 +02:00
sina
e94a86fcfb add vs2026 workflow and temporarily disabling CI CD 2026-06-19 18:45:50 +02:00
Sina Karvandi
63d509d422
Merge pull request #623 from HyperDbg/linux
Linux added new platform independent functions to the API
2026-06-19 18:22:19 +02:00
idov31
e56730ee25 Added check for whether hyper-v is the top level hypervisor 2026-06-17 20:45:32 +03:00
idov31
0f2a339e0b Added VPID check support 2026-06-17 20:34:09 +03:00
sina
70954f89b4 add v145 platform of zydis and pdbex 2026-06-15 22:55:40 +02:00
sina
622db82af5 remove old pdbex and zydis submodules 2026-06-15 22:24:36 +02:00
maxraulea
10576b064a Added typecast for wchar, mismatch on Linux and Windows 2026-06-15 16:21:12 +02:00
maxraulea
7586303ee8 revert w_char types 2026-06-15 15:57:57 +02:00
maxraulea
5e074a5cbd PE parsing compiles now 2026-06-15 15:52:50 +02:00
maxraulea
0b59876919 compiling dump.cpp and track.cpp 2026-06-15 15:18:56 +02:00
maxraulea
ced1ee94a4 Update platform-lib-calls.c 2026-06-15 14:47:42 +02:00
Sina Karvandi
b03a1f7ac2
Merge pull request #622 from HyperDbg/libipt
Some checks failed
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Libipt
2026-06-15 00:06:38 +02:00
Sina Karvandi
47ee830867
Merge pull request #619 from maxraulea/gcc-libhyperdbg
Platform ioctl interface
2026-06-15 00:04:44 +02:00
sina
4db59dc013 fix changelog and pt app issues 2026-06-15 00:04:28 +02:00
Sina Karvandi
503988e3a7
Merge pull request #620 from masoudrahimi01/libipt
Fixed ioctl pt operation size bug
2026-06-14 19:16:21 +02:00
Masoud Rahimi Jafari
dabf132d31 Fixed ioctl pt operation size bug 2026-06-14 16:29:26 +02:00
maxraulea
54b5b5a42f Platform ioctl interface 2026-06-14 14:55:02 +02:00
Sina Karvandi
60ab87875c
Update CONTRIBUTING.md 2026-06-14 01:27:28 +02:00
sina
122a99a6fe commenting synthetic MSRs 2026-06-13 15:42:40 +02:00
sina
b11da036d1 fix name of example files 2026-06-13 15:22:34 +02:00
sina
e04ee4dcc3 add Intel PT libraries 2026-06-13 14:20:32 +02:00
sina
9ad48d30dc fix new form of loading and unloading in the example app
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-06-11 14:31:10 +02:00
sina
8803e6f495 remove unused DPC definitions
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-11 00:13:25 +02:00
sina
df12e9fd79 Fix adding missing IOCTL for Intel PT 2026-06-10 23:56:36 +02:00
Sina Karvandi
ade6877a7d
Merge pull request #609 from masoudrahimi01/feat/intel-pt-integration
Feat/intel pt integration
2026-06-10 23:15:35 +02:00
Sina Karvandi
b38b43eef9
Merge branch 'dev' into feat/intel-pt-integration 2026-06-10 23:14:26 +02:00
maxraulea
f9b912d365 Fix Build files: Added new platform API filesa
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-10 16:29:35 +02:00
maxraulea
6c97d86610 Hopefully fix build errors V2 2026-06-10 16:29:35 +02:00
maxraulea
6299161980 Hopefully fix build errors 2026-06-10 16:29:35 +02:00
maxraulea
31b514f8df Interface Linux for the serial port 2026-06-10 16:29:35 +02:00
maxraulea
853ae9d5fe added defs to linux environment 2026-06-10 16:29:35 +02:00
maxraulea
5a02c43cc1 New platform lib calls 2026-06-10 16:29:35 +02:00
maxraulea
c2c0030f1b Switching cores 2026-06-10 16:29:35 +02:00
maxraulea
e048f5b822 added call to platform api and new TODO 2026-06-10 16:29:35 +02:00
maxraulea
9c3e0ed23b added Linux distinction and pragmas together with new platform functions 2026-06-10 16:29:35 +02:00
maxraulea
0e39c24f28 updates to cmake file for linux 2026-06-10 16:29:35 +02:00
sina
25871f4e48 change version 2026-06-10 16:03:38 +02:00
Sina Karvandi
014d92dc13
v0.19
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Merge pull request #611 from HyperDbg/dev
2026-06-10 01:52:04 +02:00
sina
5e5f277e21 fix race condition error in pool manager 2026-06-09 19:34:58 +02:00
sina
f3c14063c3 add beta option for versioning 2026-06-09 17:24:55 +02:00
Sina Karvandi
763ee1b4ed
Merge pull request #610 from HyperDbg/trace-module
Trace module
2026-06-09 15:06:22 +02:00
sina
cd52174d82 fix and remove unused VMM callbacks 2026-06-09 15:04:20 +02:00
sina
bb3b09beb9 replace VMM callbacks 2026-06-09 01:37:48 +02:00
sina
a6421bec2b add module checks based on command requirements 2026-06-08 23:45:43 +02:00
Sina Karvandi
642933b3d9
Update README.md 2026-06-08 14:45:23 +02:00
Sina Karvandi
1100da1a1d
Merge pull request #607 from jtaw5649/upstream/rsds-relative-paths
Use relative RSDS fixture paths
2026-06-07 22:33:37 +02:00
jtaw5649
5cc166254d test: use relative RSDS fixture paths 2026-06-07 17:07:09 +01:00
Sina Karvandi
b6f93dbc7d
Merge pull request #600 from jtaw5649/pr-symbol-memory
Load symbol identity from in-memory PE CodeView data
2026-06-07 17:07:01 +02:00
sina
6a0782d962 add doxygen and clean up 2026-06-07 16:57:53 +02:00
sina
f065776565 add missing Hyper-V TLFS headers
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-06-07 14:03:02 +02:00
Sina Karvandi
277dbb1b71
Merge pull request #606 from HyperDbg/trace-module
Trace module
2026-06-07 13:37:18 +02:00
Sina Karvandi
e05d60be7d
Merge pull request #605 from Idov31/dev
Added synthetic MSR handling
2026-06-07 13:36:19 +02:00
Sina Karvandi
b0f3fa1ffd
Merge pull request #602 from jtaw5649/upstream/transparent-mode-mask-api
Add transparent-mode evade mask selection
2026-06-07 13:28:06 +02:00
sina
6b48fec247 add load and unload all 2026-06-07 01:04:04 +02:00
sina
aa09f9cde3 check to unload the trace module before unloading vmm 2026-06-06 23:45:18 +02:00
idov31
bd30a120ae Made it a little more readable (ref: 220940ebb7/NovaHypervisor/RegistersHandler.cpp (L4)) 2026-06-06 23:02:22 +03:00
idov31
8b725c190b Added synthetic MSR handling 2026-06-06 22:56:59 +03:00
sina
0aedc66ed0 add load and unload hyper trace module 2026-06-06 17:18:14 +02:00
Masoud Rahimi Jafari
81c8b88dc3 Added disassembler to hyperdbg app to show decoded intel pt buffers 2026-06-06 15:41:48 +02:00
Sina Karvandi
67d8d461bd
Merge pull request #603 from HyperDbg/trace-module
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Trace module
2026-06-06 00:34:16 +02:00
sina
5309211043 Fix pool manager corruption of linked lists 2026-06-06 00:33:21 +02:00
sina
f274e1aaa0 check for pool manager initialization 2026-06-05 20:12:30 +02:00
jtaw5649
9fd4034855 feat(hide): add transparent evade mask API 2026-06-05 19:01:14 +01:00
sina
003b63990f add start kd driver export in SDK 2026-06-05 19:21:41 +02:00
sina
2cd620b521 move IRP closing to basic IOCTLs 2026-06-05 18:29:00 +02:00
Sina Karvandi
0841b70dc4
Merge pull request #601 from jtaw5649/fix/debugger-action-cleanup
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
Fix action cleanup list removal in debugger events
2026-06-05 16:29:19 +02:00
jtaw5649
986ef9f085 fix(debugger): unlink actions before free 2026-06-05 14:59:18 +01:00
jtaw5649
d8ee4f1e32 test(symbols): cover .sym command parsing 2026-06-04 19:15:44 +01:00
jtaw5649
3eb1de4055 feat(symbols): bound loaded PDB identity reads 2026-06-04 19:15:44 +01:00
jtaw5649
0e4ae4d081 feat(symbols): harden loaded PDB identity 2026-06-04 19:15:44 +01:00
jtaw5649
95a3305bd4 fix(symbols): validate user module details 2026-06-04 19:15:44 +01:00
jtaw5649
f7d196f36d feat(symbols): prefer loaded CodeView PDB identity 2026-06-04 19:15:44 +01:00
jtaw5649
9887fbbdac feat(symbols): prefer file-backed CodeView PDB identity 2026-06-04 18:26:11 +01:00
jtaw5649
6aca81e534 refactor(symbols): isolate PDB identity formatting 2026-06-04 18:26:11 +01:00
jtaw5649
51d5584829 test(symbols): add CodeView RSDS parser fixtures 2026-06-04 18:25:24 +01:00
Masoud Rahimi Jafari
2dc1a26f1c Added user app example for pt tracing 2026-06-04 01:55:42 +02:00
sina
adfe5f7d14 uninit VMM and KD separately 2026-06-04 00:55:05 +02:00
sina
b6b8320518 moving pool mananger from hyperhv to hyperkd 2026-06-04 00:06:41 +02:00
Sina Karvandi
f270605936
Merge pull request #599 from HyperDbg/dev
Dev
2026-06-03 18:27:11 +02:00
sina
d2bc99189b add example for loading HyperDbg from VMI mode using libhyperdbg
Some checks failed
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-06-03 17:18:35 +02:00
sina
4774db37bd add items to changelog and readme
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-02 19:57:05 +02:00
Sina Karvandi
59f9907646
Merge pull request #596 from maxraulea/script-engine-gcc
Script engine gcc
2026-06-02 19:52:04 +02:00
sina
ffb0f8ac1d fix build error on script engine refactor for Linux 2026-06-02 19:51:27 +02:00
Sina Karvandi
a0b305a7e4
Merge pull request #598 from jtaw5649/upstream/pe-bounded-metadata
Complete .pe metadata parsing with bounded PE reader
2026-06-02 19:29:00 +02:00
sina
65bcf4f4c6 integrating the new enhanced PE parser 2026-06-02 19:28:19 +02:00
Sina Karvandi
6001cc3a41
Merge pull request #595 from jtaw5649/fix/synchronous-debugger-device-handles
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
Fix synchronous debugger device IOCTL handles
2026-06-02 14:56:45 +02:00
sina
0a874d31a9 create multiple IOCTL handlers for different modules 2026-06-02 14:04:47 +02:00
jtaw5649
6155304d7f feat(pe): expand PE metadata reporting 2026-06-02 12:37:30 +01:00
jtaw5649
ac78efff1b docs(pe): refresh command help 2026-06-02 12:26:20 +01:00
jtaw5649
f212c8b6b7 feat(pe): report overlay and malformed metadata 2026-06-02 12:14:53 +01:00
jtaw5649
930378058d feat(pe): parse TLS debug and load config metadata 2026-06-02 11:43:54 +01:00
jtaw5649
2ac63b85b9 feat(pe): print PE imports and exports 2026-06-02 11:39:53 +01:00
jtaw5649
a9d64010e3 feat(pe): print PE header metadata 2026-06-02 11:29:39 +01:00
jtaw5649
ab9f508ffc refactor(pe): add bounded image reader 2026-06-02 11:20:05 +01:00
maxraulea
757738bf23 Fix for cyclic dependency that broke gcc compilation 2026-06-01 22:48:12 +02:00
maxraulea
b56f970e0a Added headers for linux compilation 2026-06-01 22:47:00 +02:00
maxraulea
e923ec451e Fix paths 2026-06-01 22:45:49 +02:00
maxraulea
d3fe58bcc7 Added extern keyword for globals for linux compilation 2026-06-01 22:44:34 +02:00
maxraulea
7e002af3a9 Definitions not present on Linux, so created empty stub 2026-06-01 22:38:53 +02:00
maxraulea
b19432ee53 Cross platform API for platform specific functions in script-engine 2026-06-01 22:37:38 +02:00
maxraulea
2d1293ff51 Add argument to Newtemp for gcc compatibility 2026-06-01 22:34:11 +02:00
maxraulea
3d5ee41bb6 change order for compilation gcc 2026-06-01 22:28:46 +02:00
maxraulea
453537dc33 update paths 2026-06-01 22:28:03 +02:00
jtaw5649
8711881d3c fix: use synchronous debugger device handles 2026-06-01 20:30:31 +01:00
sina
bf2f752116 Fix hyperlog callback path in the project
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-06-01 15:35:55 +02:00
sina
95cd3e7c64 Merge branch 'dev' of https://github.com/HyperDbg/HyperDbg into dev 2026-06-01 14:07:16 +02:00
sina
dd44025dde refactor doxygen, variables, function names 7 2026-06-01 14:07:01 +02:00
Sina Karvandi
e8181b4d9b
Merge pull request #593 from jtaw5649/fix/hyperevade-hide-gate
Fix !hide HyperEvade activation guard
2026-06-01 13:35:15 +02:00
jtaw5649
83b507e672 fix: correct HyperEvade hide guard 2026-06-01 11:46:43 +01:00
Sina Karvandi
e16c31517e
Merge pull request #592 from maxraulea/linux-stub
Linux stub
2026-06-01 11:26:23 +02:00
Masoud Rahimi Jafari
d6f56065d5 Changed intel pt files author email 2026-06-01 11:21:00 +02:00
maxraulea
25371439df Added Linux distinction for generating build files 2026-05-31 21:17:03 +02:00
maxraulea
6b0ebd3e47 Linux Compatibility script-engine headers 2026-05-31 21:16:07 +02:00
maxraulea
bca5a245a7 Linux Compatibility hyperdbg-cli.cpp 2026-05-31 21:16:07 +02:00
maxraulea
7592b12979 SDK export Linux compatibility 2026-05-31 21:16:06 +02:00
sina
e0af5afd4f fix independently unloading the kd module
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-05-31 21:03:02 +02:00
Sina Karvandi
3753bcd43d
Merge pull request #591 from HyperDbg/trace-module
Trace module
2026-05-31 19:58:57 +02:00
sina
0cd11e136b Fix build issues of the Intel PT in hypertrace 2026-05-31 19:58:18 +02:00
Sina Karvandi
5b8076510a
Merge pull request #590 from HyperDbg/dev
Dev
2026-05-31 19:39:28 +02:00
Sina Karvandi
01e513c876
Merge branch 'trace-module' into dev 2026-05-31 19:39:14 +02:00
sina
cbb28edde3 refactor doxygen, variables, function names 7 2026-05-31 19:29:14 +02:00
Sina Karvandi
b7bcbf2f46
Merge pull request #589 from masoudrahimi01/feat/intel-pt-integration
Feat/intel pt integration
2026-05-31 19:14:10 +02:00
Sina Karvandi
34dfe5604b
Merge branch 'dev' into feat/intel-pt-integration 2026-05-31 19:13:36 +02:00
sina
ef2a482c45 refactor doxygen, variables, function names 6 2026-05-31 18:59:52 +02:00
sina
1e49d3f05c refactor doxygen, variables, function names 5 2026-05-31 18:34:03 +02:00
sina
eeeff45f70 fix refactoring issues 2026-05-31 16:38:21 +02:00
sina
6bcd4a3b10 refactor doxygen, variables, function names 4 2026-05-31 03:21:19 +02:00
sina
3bb181fb7d refactor doxygen, variables, function names 2 2026-05-31 03:17:53 +02:00
sina
5fb4c24fe4 refactor doxygen, variables, function names 2 2026-05-31 02:21:47 +02:00
sina
ff1f499b9f refactor doxygen, variables, function names 1 2026-05-30 20:58:09 +02:00
sina
6eca8c6c85 refactor code convention in hyperlog 2026-05-30 15:54:20 +02:00
sina
e31731cd37 remove unused extern variables 2026-05-29 00:34:08 +02:00
sina
d669d93d81 add packet and messaging files 2026-05-29 00:10:44 +02:00
sina
cb5a83096d load trace module 2026-05-28 20:26:33 +02:00
sina
468927a30f export LBR type as an argument on HyperTrace
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-05-28 14:41:37 +02:00
sina
0a279b5dba check IOCTL to load VMM module 2026-05-27 20:21:21 +02:00
sina
167931fc01 load the vmm module over IOCTL instead of CreateFile 2026-05-26 19:52:04 +02:00
sina
81f3d9f3d2 export HyperTrace LBR support and capacity function to the VMM and HyperEvade module
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-05-26 16:41:23 +02:00
sina
37cb28e910 add export to LBR support flag and LBR capacity on HyperTrace 2026-05-26 16:22:33 +02:00
Sina Karvandi
b56e34c3d2
Merge pull request #588 from HyperDbg/LBR3
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
Lbr3
2026-05-25 20:28:32 +02:00
sina
33c3513184 fix message layout of LBR printing and add notes to lbr help 2026-05-25 20:18:54 +02:00
sina
a8f259fbad fix #587 to add functions with no input and return a number 2026-05-25 16:26:26 +02:00
sina
686e445c9b fix LBR filter issue and dumping message format 2026-05-25 15:29:42 +02:00
sina
02ab868dc7 add lbr_restore and lbr_restore_by_filter functions
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-05-24 23:51:12 +02:00
sina
1a63f6e737 enhance the LBR check function
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-05-24 15:43:48 +02:00
Masoud Rahimi Jafari
e5652fbf7f Debug compile errors for intel pt 2026-05-20 01:57:32 +02:00
Masoud Rahimi Jafari
434aed98d0 Added pt pause, resume and size commands 2026-05-19 05:13:22 +02:00
Masoud Rahimi Jafari
59280239e9 Added pt mmap comand and function 2026-05-19 03:50:26 +02:00
Sina Karvandi
6871741ee0
Merge pull request #586 from HyperDbg/LBR2
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Lbr2
2026-05-18 16:57:06 +02:00
sina
5fb797c201 fix output buffer IOCTL checks for WRMSR 2026-05-17 20:18:36 +02:00
sina
1369aa777b refactor IOCTL codes 2026-05-17 17:07:59 +02:00
Sina Karvandi
13ccf7c9b0
Merge pull request #585 from orbisai0security/fix-v-004-memcpy-zero-size-validation
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
fix: scriptenginefunctionmemcpy exposes a kernel-mod... in...
2026-05-17 12:40:13 +02:00
orbisai0security
1c5f4f3853 fix: V-004 security vulnerability
Automated security fix generated by Orbis Security AI
2026-05-17 04:43:55 +00:00
sina
ef1ce11154 check LBR support within nested virtualization environments 2026-05-17 04:57:09 +02:00
sina
61c30822fb perform adjustments for call_stack filter option of LBR 2026-05-17 04:27:56 +02:00
Masoud Rahimi Jafari
64328723c8 Added Intel-PT to hypertrace 2026-05-17 03:18:05 +02:00
sina
517872e072 create new fields to show branch type in ARCH LBR 2026-05-17 02:39:58 +02:00
sina
4ea5b142f4 fix LBR filter on ARCH LBR CTL
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-05-15 20:23:52 +02:00
sina
f6fd116274 add new arch-based TO and FROM MSRs 2026-05-15 17:25:56 +02:00
Sina Karvandi
dfec8d0cb2
Merge pull request #584 from HyperDbg/linux-refactoring
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
Linux refactoring
2026-05-12 14:58:05 +02:00
sina
90337d37f7 refactoring codes for platform independence of hyperlog and hypertrace and script-eval 2026-05-10 00:58:47 +02:00
sina
af3b3e2f71 fix compiling error for user and kernel intrinsics in Linux 2026-05-08 18:58:20 +02:00
sina
10dd66d416 add synchronization functions for DPC routines of Windows 2026-05-08 16:44:42 +02:00
sina
9bf3916909 add user level modifications for intrinsics support in mock 2026-05-06 00:50:29 +02:00
sina
ef1a9cd1f7 add linux implementation of intrinsics functions 2026-05-05 23:59:31 +02:00
sina
858434940a add CPU intrinsics for user mode 2026-05-05 23:46:12 +02:00
sina
1a4f02f6df Merge branch 'dev' of https://github.com/HyperDbg/HyperDbg into dev
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-05-05 22:10:02 +02:00
sina
10dfa43696 add articles to README and CHANGELOG 2026-05-05 22:09:51 +02:00
Sina Karvandi
90295d7c13
Merge pull request #582 from HyperDbg/LBR
Lbr
2026-05-05 21:49:32 +02:00
sina
de0c56b466 create platform independent intrinsics functions 2026-05-05 21:25:20 +02:00
sina
e816b93c46 add missing LBR VMCALL 2026-05-04 14:23:53 +02:00
Sina Karvandi
77a6a0fb87
Merge pull request #581 from HyperDbg/LBR
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
add lbrdump command and sdk function
2026-05-04 00:33:53 +02:00
sina
09416e7fe1 add lbrdump command and sdk function 2026-05-04 00:29:54 +02:00
sina
ea74b06286 apply automatic save for printing lbr records
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-05-03 01:45:02 +02:00
Sina Karvandi
c767f40875
Merge pull request #580 from HyperDbg/LBR
Lbr
2026-05-03 01:27:01 +02:00
sina
19b9ebe3fd add lbrdump command 2026-05-03 01:25:39 +02:00
sina
8b593489e7 change functions of LBR 2026-05-03 01:03:19 +02:00
sina
ee72dd5f3f convert all VMX instructions to platform independent functions 2026-05-02 19:04:09 +02:00
sina
4e26d65626 add gitignore for files copied to the Linux mock 2026-05-02 17:49:15 +02:00
sina
0ef8a15ed4 port intrinsics functions to linux 2026-05-02 17:38:33 +02:00
sina
02e459d5f6 change setting LBR kernel status code 2026-05-02 16:53:36 +02:00
sina
aa80cd9d6b Apply all ARCH Based LBR controls on API level 2026-05-01 20:39:13 +02:00
sina
6f004f1ffd Add ARCH LBR functions from hypervisor 2026-05-01 18:40:39 +02:00
sina
1ad7bac9ce check for ARCH and legacy LBR support 2026-04-30 20:29:22 +02:00
sina
469f12c645 compile HyperDbg SDK for Linux (user-mode)
Some checks failed
vs2022-ci / win-amd64-build (debug, x64) (push) Has been cancelled
vs2022-ci / win-amd64-build (release, x64) (push) Has been cancelled
vs2022-ci / Deploy release (push) Has been cancelled
2026-04-28 17:17:45 +02:00
sina
d3f4e65686 Replace general types with basic types
Some checks are pending
vs2022-ci / win-amd64-build (debug, x64) (push) Waiting to run
vs2022-ci / win-amd64-build (release, x64) (push) Waiting to run
vs2022-ci / Deploy release (push) Blocked by required conditions
2026-04-28 15:03:08 +02:00
sina
c5ba5ccd89 compile HyperDbg SDK for Linux 2026-04-28 14:39:54 +02:00
sina
b35e0dd43c clearing the headers for Windows and Linux 2026-04-28 01:24:43 +02:00
sina
dc085fbe2a remove PlatformTypes and merge it to GeneralTypes 2026-04-27 23:55:04 +02:00
sina
f1f0e50e08 create empty pch hearder for linux compiler 2026-04-27 23:23:01 +02:00
sina
d3cfd7b5d9 create different headers for basic types in Linux 2026-04-27 21:22:43 +02:00
sina
71fedff180 add basic structure of intrinsics functions 2026-04-27 16:53:36 +02:00
sina
7c6ca98358 change git ignore for linux kernel modules 2026-04-27 16:17:46 +02:00
Sina Karvandi
2f8e7f9029
Merge pull request #579 from HyperDbg/LBR
Lbr
2026-04-27 03:18:11 +02:00
sina
af50093b9b apply LBR filters from VMX-root mode 2026-04-27 03:16:41 +02:00
sina
f5c45c7ebb add filtering options to LBR 2026-04-27 00:50:41 +02:00
sina
93ac084d4b show branch misprediction and cycle count 2026-04-26 21:02:38 +02:00
Sina Karvandi
8a934e93c8
Merge pull request #578 from HyperDbg/LBR
Lbr
2026-04-26 12:38:05 +02:00
sina
84f0fa0ed4 check for the VMX state independently from function arguments 2026-04-26 12:37:08 +02:00
sina
76d91901cd add lbr_flush function to the script engine 2026-04-26 02:23:04 +02:00
sina
c6b6a8a3a0 add processor trace command 2026-04-25 22:46:55 +02:00
sina
e359911d60 add base structure for Intel PT 2026-04-25 21:42:17 +02:00
sina
3cbf328fee Restructure of the hypertrace project 2026-04-25 18:02:48 +02:00
Sina Karvandi
512e7fe290
Merge pull request #577 from HyperDbg/LBR
Lbr
2026-04-24 20:05:28 +02:00
sina
70f6613953 add lbr_save and lbr_dump script engine functions for accessing LBR commands 2026-04-24 20:04:30 +02:00
sina
566d38c39a create dmp function to enable, disable, save, and dump LBR branches 2026-04-24 18:35:15 +02:00
sina
03162c06ee remove unused LBR functions 2026-04-24 17:24:18 +02:00
sina
81869ec715 dump LBR based on TOS MSR 2026-04-24 17:16:11 +02:00
sina
7130daf65d remove unnecessary codes for LBR 2026-04-23 19:58:51 +02:00
sina
8f76929643 comment non-used codes for LBR 2026-04-23 19:33:10 +02:00
sina
d930b3341d change LBR control VMWRITE length 2026-04-23 18:52:41 +02:00
Sina Karvandi
54c2a9923b
Merge pull request #576 from HyperDbg/LBR
Lbr
2026-04-23 16:44:08 +02:00
sina
24875bda88 apply VM-exit and VM-entry load and save controls from VMCALLs 2026-04-23 16:42:34 +02:00
Sina Karvandi
54fd52a924
Merge pull request #575 from HyperDbg/copilot/find-typos-and-fix-copy-paste
Fix typos and copy-paste wording issues
2026-04-23 14:51:51 +02:00
copilot-swe-agent[bot]
774d61782f
fix: correct typos and one copy-paste error in comments and messages
Agent-Logs-Url: https://github.com/HyperDbg/HyperDbg/sessions/0817c887-8808-4080-a701-6a0211b10595

Co-authored-by: SinaKarvandi <13383992+SinaKarvandi@users.noreply.github.com>
2026-04-23 12:38:48 +00:00
sina
f2ef1c3f3b Fix the problem of not applying the EAX index in the CPUID event extension command 2026-04-22 18:24:09 +02:00
sina
f192c194df initialize the LBR based on hypervisor environment checks 2026-04-22 17:43:23 +02:00
sina
efded3790b protect load and save vm-entry and vm-exit controls from setting and unsetting in different routines 2026-04-22 16:27:20 +02:00
Sina Karvandi
4d4045674a
Merge pull request #574 from HyperDbg/LBR
Lbr
2026-04-19 20:10:12 +02:00
sina
111bead68d check for hypervisor support of load and save VMCS exit and entry controls 2026-04-19 20:08:47 +02:00
sina
6e511c8368 create different function separations for DPCs and Broadcasting routines 2026-04-19 19:34:13 +02:00
sina
43cdab9821 broadcast LBR example to all cores 2026-04-19 19:20:18 +02:00
sina
a1984fed70 change instances for VMWRITE into a single function 2026-04-19 16:57:48 +02:00
sina
01ae55f854 change VMREAD to a specific function 2026-04-19 15:57:52 +02:00
sina
2ad4fa56ee create separate example for LBR 2026-04-19 15:49:12 +02:00
sina
f36273aba7 add VMCALL option to LBR tracing 2026-04-14 19:44:41 +02:00
sina
1b08f14add add cross VMCALLs for setting core-specific LBR state 2026-04-14 19:23:51 +02:00
sina
a1d30abdf2 remove VMX instructions from hypertrace in favor of linking to hyperhv callbacks 2026-04-14 17:53:54 +02:00
sina
65c1a6aef9 v0.18.1 (release) 2026-04-09 17:32:30 +02:00
Sina Karvandi
00f889778c
v0.18.1
Merge pull request #573 from HyperDbg/dev
2026-04-09 17:19:10 +02:00
sina
13a2bc6368 Update CHANGLELOG.md 2026-04-09 17:17:49 +02:00
sina
15f8b3cca1 apply vmx-root LBR to VMCS 2026-04-06 20:17:40 +02:00
sina
6abfc0ec46 pass VMX root state over LBR 2026-04-06 19:55:08 +02:00
sina
c266a880c3 add lbr start and lbr stop functions to the script engine 2026-04-06 18:33:01 +02:00
sina
201820376d enable and disable LBR separately from the HyperTrace module 2026-04-06 16:45:35 +02:00
sina
1dd73675e9 apply the LBR and HyperTrace initialization and operations 2026-04-06 01:05:59 +02:00
sina
2329fd3c19 add user mode side of initializing LBR 2026-04-05 22:56:59 +02:00
sina
e040a1c711 fix .clang-format error 2026-03-15 21:53:58 +01:00
sina
fba6f66e1a minor refactor and modify changelog 2026-02-24 15:48:23 +01:00
Sina Karvandi
1337980ec3
Merge pull request #569 from ShirokoLEET/dev
Fix #567
2026-02-24 15:24:35 +01:00
ShirokoLEET
bff7f7b7c3 fix by change to tracking VA when split pages 2026-02-20 23:14:37 +08:00
Sina Karvandi
9b15c762c8
Merge pull request #568 from harimishal1/dev
hypertrace
2026-02-20 15:08:02 +01:00
Hari Mishal
3691c5e343 more comments changed 2026-02-19 21:07:59 +01:00
Hari Mishal
815e1b0ef9 changed some comments 2026-02-19 20:51:03 +01:00
Hari Mishal
95c37166e7 Merge branch 'dev' of https://github.com/harimishal1/Hyperdbg into dev 2026-02-19 20:47:17 +01:00
Hari Mishal
b0a839222b hypertrace now works when you load the vmm. call has been commented out 2026-02-19 20:33:24 +01:00
sina
aa0a9ff7ee change version and fix CHANGELOG 2026-02-16 13:37:08 +01:00
Sina Karvandi
a6f841c380
v0.18
Merge pull request #566 from HyperDbg/dev
2026-02-15 22:28:42 +01:00
Sina Karvandi
0638660e31
Merge pull request #565 from HyperDbg/update-zydis
Update zydis
2026-02-13 16:07:48 +01:00
sina
bc2779f1c1
add updated version of zydis to fix new WDK error 2026-02-13 16:05:35 +01:00
sina
aafc61457f
removed zydis submodule to update 2026-02-13 15:29:51 +01:00
sina
6e0aee6c01
add information for current state of supporting linux 2026-02-13 15:25:45 +01:00
Sina Karvandi
4dc64331f6
Merge pull request #563 from Alish14/linux-driver
Linux driver
2026-02-13 14:57:38 +01:00
Alireza moradi
ae8ce290c1 change dummy file header location and some changes in makefile 2026-02-13 12:25:26 +03:30
Alireza moradi
0f60d24921 change include path in mock.c 2026-02-13 12:25:26 +03:30
Alireza moradi
f5c54341ac change linux mock makefile 2026-02-13 12:25:26 +03:30
alish14
9e8dcba265 add dummy pch for handling error in linux 2026-02-13 12:25:26 +03:30
alish14
3a21e72f32 add README 2026-02-13 12:25:26 +03:30
alish14
44f79b6bb9 add if condition macro in PlatformMem for including header only in windows 2026-02-13 12:25:26 +03:30
alish14
f40f1d8183 fix dependecies after changing file names and now it work 2026-02-13 12:25:05 +03:30
alish14
0ffe8c714c change arch and file names 2026-02-13 12:12:44 +03:30
alish14
5f00c98583 updates cmakes 2026-02-13 12:12:44 +03:30
alish14
b12e3d06a9 fixed comment 2026-02-13 12:12:44 +03:30
alish14
8f97858987 refactor(Mem.c): cross-platform memory API and fix build system 2026-02-13 12:12:44 +03:30
Alireza moradi
e229d85baa change make file for include path be dynamic not hardcoded 2026-02-13 12:12:44 +03:30
Alireza moradi
85a3a48cd2 delete not needed file 2026-02-13 12:12:44 +03:30
Alireza moradi
79f39a35a6 delete not needed file 2026-02-13 12:12:44 +03:30
Alireza moradi
a25f81483c link files in mock to platform/kernel/ 2026-02-13 12:12:44 +03:30
Alireza moradi
1eb72d1621 linux kernel module mock added 2026-02-13 12:12:44 +03:30
sina
91c558e43b
disable hypertrace callback by default 2026-02-11 18:17:09 +01:00
sina
207772f0e7
edit changelog 2026-02-11 18:16:04 +01:00
Sina Karvandi
9b9bdb3af6
Merge pull request #564 from harimishal1/dev
Uncommented call to hypertrace in Loader.c and added dependencies (lbr.h, lbr.c) and code (tracing.c) to print lbr buffer.
2026-02-11 17:58:30 +01:00
Hari Mishal
1924385156 Uncommented call to hypertrace in Loader.c and added dependencies (lbr.h, lbr.c) and code (tracing.c) to print lbr buffer. 2026-02-11 02:54:02 +01:00
sina
20984b36b5
update version and changelog 2026-02-08 19:49:22 +01:00
sina
5a42d00a1f
Link hypertrace to hyperkd 2026-02-08 04:09:47 +01:00
sina
37569a3ae6
separate LBR from general tracing routine in hypertrace 2026-02-08 03:50:25 +01:00
sina
a0bd050330
Fix hyperlog linking issues and redirect DbgPrints to LogInfo in hypertrace project 2026-02-08 03:35:04 +01:00
sina
5e3e0d4081
import hyperlog into hypertrace and import and export hypertrace routines 2026-02-08 03:02:43 +01:00
sina
569881c1c1
refactoring and add function information 2026-02-07 23:33:36 +01:00
sina
e25209453a
renaming and refactoring hypertrace project 2026-02-07 22:29:25 +01:00
Sina Karvandi
88b134c50f
Merge pull request #562 from harimishal1/dev
added tracing.h and tracing.c
2026-02-06 14:59:27 +01:00
Hari Mishal
cd5aae1b16 added all supported cpus to tracing.c 2026-02-03 17:52:53 +01:00
Hari Mishal
ef705fccc7 added tracing.h and tracing.c 2026-02-03 17:29:37 +01:00
Sina Karvandi
72145109ab
Merge pull request #561 from xmaple555/dev
add include file in script engine
2026-01-08 00:09:18 +01:00
xmaple21215
a7ceabdc33 update post-build event in script-engine 2026-01-06 17:03:17 +08:00
xmaple21215
8bd8950514 add include file in script engine 2026-01-06 16:38:22 +08:00
Sina Karvandi
c2e2fe5c4b
Merge pull request #560 from harimishal1/dev
add base code for the hypertrace project
2025-12-02 19:10:26 +01:00
Hari Mishal
19437cd694 add base code for the hypertrace project 2025-12-02 19:08:27 +01:00
Sina Karvandi
338677a0fb
Update CONTRIBUTING.md 2025-12-02 15:20:08 +01:00
Sina Karvandi
5462d69dd1
v0.17
Merge pull request #559 from HyperDbg/dev
2025-11-10 14:55:06 +01:00
sina
2158fc18da
Change version and update changelog 2025-11-09 19:52:48 +01:00
Sina Karvandi
898ae8cbce
Merge pull request #556 from xmaple555/dev
update array index for boolean expression in script engine
2025-10-26 14:31:49 +01:00
xmaple555
82540bab5e update array index for boolean expression in script engine 2025-10-26 12:15:41 +08:00
Sina Karvandi
ba2cec3c12
Merge pull request #555 from HyperDbg/fix-script-variable-type
fix script variable type
2025-10-21 14:16:09 +02:00
sina
43b0245fa1
fix script variable type 2025-10-21 12:56:21 +02:00
Sina Karvandi
ed2759402a
Merge pull request #554 from xmaple555/dev
add array and pointer in script engine
2025-10-21 11:53:17 +02:00
xmaple555
8b4178d416 add array and pointer in script engine 2025-10-21 16:46:49 +08:00
xmaple555
4233ade781 update pointer variable type in script engine 2025-10-15 08:01:17 +08:00
Sina Karvandi
35f3f3eec8
Merge pull request #553 from xmaple555/dev
fix dd_pa in scrpt-engine
2025-10-13 18:22:54 +02:00
xmaple555
3577876cac fix dd_pa in scrpt-engine 2025-10-14 00:09:58 +08:00
Sina Karvandi
22096da60e
v0.16
Merge pull request #551 from HyperDbg/dev
2025-09-08 00:11:00 +02:00
sina
2ec5747539
remove the requirement for the r in the user debugger 2025-09-07 00:17:37 +02:00
unknown
e837a4526b perform upausing threads before changing MBEC bits 2025-09-06 23:11:08 +02:00
Sina Karvandi
6fb000ce89
Merge pull request #550 from HyperDbg/user-debugger2
User debugger2
2025-09-06 20:30:31 +02:00
sina
228ecd91f1
added support for the print and the printf functions in the user debugger 2025-09-06 19:25:26 +02:00
unknown
0338f9b301 remove IRP sleep for debuggee manadatory bit operation codes 2025-09-06 16:44:25 +02:00
unknown
f3b952805b export SDK API for evaluating expressions based on the user or the kernel debugger context 2025-09-02 01:11:03 +02:00
unknown
8316085e17 fix command parameter parsing errors on the user debugger 2025-09-02 00:52:27 +02:00
sina
0d940ee543
sending results of format to the user debugger 2025-09-01 18:27:01 +02:00
sina
fe4f2be270
run script for the .formats command in the user debugger 2025-09-01 15:00:21 +02:00
sina
cda5029081
run script for the print command in the user debugger 2025-09-01 14:38:59 +02:00
sina
31fc581135
add support to the eval command in the user debugger 2025-08-31 18:31:35 +02:00
sina
3f6d837a62
run script for modifying registers in the user debugger 2025-08-31 16:53:09 +02:00
unknown
a869065718 add support to the registers command to the user debugger 2025-08-31 01:53:29 +02:00
unknown
85debe2636 add synchronization functions 2025-08-30 03:55:15 +02:00
unknown
87f32fb5d0 add user debugger command synchronization event 2025-08-30 03:37:10 +02:00
unknown
99b807dd6e add codes to support the p command in the user debugger 2025-08-30 00:14:48 +02:00
Sina Karvandi
82340d2c7e
Merge pull request #548 from HyperDbg/user-debugger
User debugger (progress)
2025-08-27 23:16:58 +02:00
sina
05b27083b2
fix running step-in command in user debugger 2025-08-27 23:14:57 +02:00
sina
739d143393
show number of blocked context switches 2025-08-23 15:36:53 +02:00
sina
c37ec6f3c0
apply command to the target thread from MBEC 2025-08-23 01:30:12 +02:00
Sina Karvandi
b2056dfe34
Refine README content and formatting
Updated README.md to enhance clarity and fix formatting issues.
2025-08-22 00:54:12 +02:00
Sina Karvandi
1429f2e289
Merge pull request #547 from HyperDbg/xsetbv
Xsetbv
2025-08-21 20:16:19 +02:00
sina
13f2b63053
fix checks for parameters of the XSETBV extension command 2025-08-21 19:48:37 +02:00
sina
8e111d93c6
remove extra code from XSETBV command 2025-08-21 00:39:35 +02:00
sina
77029f330d
add XSETBV event extension command 2025-08-21 00:17:26 +02:00
sina
cb9c61af29
update changelog with PR modifications 2025-08-20 18:18:39 +02:00
Sina Karvandi
91831c0d95
Merge pull request #545 from unlockable/monitor_bug_fix
Fix: An infinite vm-exit bug for !monitor x command
2025-08-20 17:02:11 +02:00
Sina Karvandi
66a1b6c6c4
Merge pull request #546 from HyperDbg/copilot/fix-33769209-15df-4e76-ba70-38c59b37adba
Fix grammar and spelling errors throughout HyperDbg codebase
2025-08-20 17:01:19 +02:00
copilot-swe-agent[bot]
972786821f Fix additional grammar/spelling: contractions, duplicate words, hyphenation
Co-authored-by: SinaKarvandi <13383992+SinaKarvandi@users.noreply.github.com>
2025-08-20 12:54:26 +00:00
copilot-swe-agent[bot]
8a5f696544 Fix grammar and spelling errors: perfrom->perform, occured->occurred, recieved->received
Co-authored-by: SinaKarvandi <13383992+SinaKarvandi@users.noreply.github.com>
2025-08-20 12:49:07 +00:00
copilot-swe-agent[bot]
e13e6a8f42 Initial plan 2025-08-20 12:38:55 +00:00
Seonjin Hwang
bc6010d061 Fix: after patch 0.14, there is an infinite vm-exit bug for \!monitor x which freeze hyperdbg. It simply fixs the bug 2025-08-20 14:53:38 +09:00
sina
c655a7705e
avoid saving and restoring nonvolatile XMM registers 2025-08-18 21:54:21 +02:00
Sina Karvandi
9bd5ffc7b9
v0.15 (release 2)
Merge pull request #544 from HyperDbg/dev
2025-08-18 00:34:38 +02:00
sina
a949bf66cd
temporarily hyperevade project 2025-08-18 00:30:13 +02:00
Sina Karvandi
77422be3dd
v0.15
Merge pull request #543 from HyperDbg/dev
2025-08-17 23:34:28 +02:00
sina
3ce7e7d92b
update preactivating mode command messages 2025-08-17 22:57:46 +02:00
sina
613dff02eb
re-enable the .start command and update changelog 2025-08-17 22:08:20 +02:00
Sina Karvandi
d2893ab5cc
Merge pull request #542 from HyperDbg/syscall-cet-support
Syscall cet support
2025-08-17 17:41:30 +02:00
sina
16f64afd4f
check for the compatibility of Intel CET to for emulating SYSCALL and SYSRET 2025-08-17 17:33:13 +02:00
sina
61d45c518d
move pool allocations to a single function 2025-08-17 16:25:02 +02:00
sina
ece94e748f
update ia32-doc submodule to update the correct value for VMCS PL3 SSP 2025-08-17 16:17:16 +02:00
sina
fae3290ec1
remove the ia32-doc dependencies 2025-08-17 16:14:11 +02:00
sina
39920ccfa5
change VMX headers to IA32doc headers 2025-08-17 14:26:38 +02:00
sina
360b0e5863
support CET SYSCALL emulation on VMCS 2025-08-17 13:51:32 +02:00
sina
cdadcfaded
add CET emulation for syscall extension command 2025-08-14 12:21:53 +02:00
Sina Karvandi
57b4b6f4e2
Merge pull request #541 from HyperDbg/save-restore-xmm-regs
Save and restore XMM registers on VM-exits
2025-08-10 01:10:12 +02:00
Sina Karvandi
4a4b1fab25
Merge branch 'dev' into save-restore-xmm-regs 2025-08-10 01:09:48 +02:00
sina
00c0add449
Restore XMM registers before VMXOFF 2025-08-09 23:45:40 +02:00
sina
faadc9272d
refactor PE parser codes 2025-08-09 14:59:00 +02:00
Sina Karvandi
82fa6ec316
Merge pull request #540 from Alish14/pe-rich-fix
Pe rich fix
2025-08-09 14:54:06 +02:00
alish14
6cb90d80d7 fix initializing format 2025-08-09 08:02:04 +03:30
alish14
38c917e1ec fixed incorrectly using pointer 2025-08-09 07:55:22 +03:30
alish14
da717d0deb change global variable to pointer 2025-08-09 06:07:22 +03:30
sina
6ea7989d51
refactoring rich header codes 2025-08-06 20:28:40 +02:00
Sina Karvandi
4d79ee1f80
Merge pull request #539 from Alish14/enhance-pe-rich
Enhance pe rich
2025-08-06 19:46:57 +02:00
alish14
76adc4ff75 add comment and change rich header displaying format 2025-08-05 04:49:48 +03:30
alish14
7baec5ebed header alias moved 2025-08-05 04:49:10 +03:30
alish14
af3c228bed add rich parser code 2025-08-04 05:21:49 +03:30
alish14
7b03230a42 add Rich header entries struct 2025-08-04 05:21:16 +03:30
sina
464e7c6736
Fix unloading (VMXOFF) crash when restoring XMM registers 2025-08-03 23:31:49 +02:00
sina
3f877c36f5
create XMM register structures for VM-entries 2025-08-03 01:18:58 +02:00
sina
853e5c9511
save and restore XMM registers and enable hyperevade optimization 2025-08-03 00:41:28 +02:00
Sina Karvandi
cbead678ea
Merge pull request #538 from HyperDbg/smi-command
SMI command
2025-08-03 00:15:58 +02:00
sina
11f8c2ebed
update changelog and change the help message of SMI command 2025-08-03 00:13:37 +02:00
sina
3961196112
add support for SMI related functionalities 2025-08-02 23:18:18 +02:00
sina
2e4269b5d3
change versioning and README.md 2025-07-27 20:08:10 +02:00
Sina Karvandi
5d8d3ca524
v0.14.1
Merge pull request #537 from HyperDbg/dev
2025-07-27 19:33:05 +02:00
sina
373158da82
fix the building issues with the bp and the .start commands 2025-07-27 19:31:08 +02:00
sina
2fdf0f59de
Restore release build optimizations and fix CPUID register restoration 2025-07-26 01:53:43 +02:00
Sina Karvandi
633ea9cb4a
Update CREDITS.md 2025-07-24 01:09:16 +02:00
508 changed files with 46233 additions and 10040 deletions

View file

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

View file

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

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

@ -0,0 +1,99 @@
name: vs2026-ci
on:
push:
branches:
- '**' # matches all branch names, including ones with slashes
tags:
- 'v*'
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
pull_request:
paths-ignore:
- '.gitignore'
- '.gitattributes'
- '**.cmd'
- '**.bat'
- '**.md'
env:
SOLUTION_FILE_PATH: ./hyperdbg/hyperdbg.sln
RELEASE_ZIP_FILE_NAME: hyperdbg
BUILD_BIN_DIR: ./hyperdbg/build/bin/
jobs:
win-amd64-build:
runs-on: windows-2025-vs2026
strategy:
matrix:
BUILD_CONFIGURATION: [release, debug]
PLATFORM: [x64]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Checkout submodules recursively
run: git submodule update --init --recursive --remote
- name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v3
- name: Setup NuGet
uses: NuGet/setup-nuget@v2
- name: Restore NuGet packages
run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Update vcxproj files
run: python utils/replace-sdk-wdk.py
- name: Build HyperDbg solution
working-directory: ${{env.GITHUB_WORKSPACE}}
run: msbuild /m /p:Configuration=${{matrix.BUILD_CONFIGURATION}} /p:Platform=${{matrix.PLATFORM}} ${{env.SOLUTION_FILE_PATH}}
- name: Upload build directory
uses: actions/upload-artifact@v4.4.0
with:
name: build_files_${{matrix.BUILD_CONFIGURATION}}
path: ${{ env.BUILD_BIN_DIR }}
deploy-release:
name: Deploy release
needs: win-amd64-build
runs-on: windows-2025-vs2026
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download build files from "build" job
uses: actions/download-artifact@v4.1.7
with:
name: build_files_release
path: ${{ env.BUILD_BIN_DIR }}
- name: Archive release
uses: thedoctor0/zip-release@master
with:
path: ${{ env.BUILD_BIN_DIR }}release/
type: 'zip'
filename: ${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
${{env.RELEASE_ZIP_FILE_NAME}}-${{ github.ref_name }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

18
.gitmodules vendored
View file

@ -1,15 +1,15 @@
[submodule "hyperdbg/dependencies/ia32-doc"]
path = hyperdbg/dependencies/ia32-doc
url = https://github.com/HyperDbg/ia32-doc.git
[submodule "hyperdbg/dependencies/zydis"]
path = hyperdbg/dependencies/zydis
url = https://github.com/HyperDbg/zydis.git
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git
[submodule "hyperdbg/tests/script-engine-test"]
path = hyperdbg/tests/script-engine-test
url = https://github.com/HyperDbg/script-engine-test.git
[submodule "hyperdbg/miscellaneous/constants/pciid"]
path = hyperdbg/miscellaneous/constants/pciid
url = https://github.com/HyperDbg/pciids
[submodule "hyperdbg/dependencies/ia32-doc"]
path = hyperdbg/dependencies/ia32-doc
url = https://github.com/HyperDbg/ia32-doc.git
[submodule "hyperdbg/dependencies/pdbex"]
path = hyperdbg/dependencies/pdbex
url = https://github.com/HyperDbg/pdbex.git
[submodule "hyperdbg/dependencies/zydis"]
path = hyperdbg/dependencies/zydis
url = https://github.com/HyperDbg/zydis.git

View file

@ -4,6 +4,192 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.21.0.0] - 2026-07-05
New release of the HyperDbg Debugger.
### Added
- Added structure for the hyperperf (Hardware Performance Counter) project ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- The 'unload' command checks whether any module is loaded or not ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
- Exported SDK API for checking whether any module is loaded or not ([link](https://github.com/HyperDbg/HyperDbg/commit/19e47c804f50f5dbb698f314e66b7d685a87ac1f))
- Added user mode and kernel mode PT parameter parser ([link](https://github.com/HyperDbg/HyperDbg/pull/631))
- Added thread (TID) and process (PID) helper functions for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/pull/633))
### Changed
- Separated SDK libraries for user mode and kernel mode modules ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- Added hypertrace, hyperevade, and hyperperf DLL files to SDK ([link](https://github.com/HyperDbg/HyperDbg/commit/c17ebc09c4d199a642352e66feebb3159582196c))
- Fix pool manager uninitialize list corruption ([link](https://github.com/HyperDbg/HyperDbg/pull/629))
- Fix 'access denied' error on loading all modules using 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))([link](https://github.com/HyperDbg/HyperDbg/commit/2b818a5116d80d466aab7b343d4aa9d1d640f082))
- Fix the concatenation error for the "hyperkd" string on the hypertrace project (https://github.com/HyperDbg/HyperDbg/commit/2b0cc18899ff532d9d590a71bf880fee5456c15f))
- Organized header files for the libhyperdbg project ([link](https://github.com/HyperDbg/HyperDbg/pull/632))
## [0.20.0.0-beta] - 2026-06-21
New release of the HyperDbg Debugger.
### Added
- Added the libipt library to the project and the SDK
- Added Intel Processor Trace (PT) example app
- Added Linux distinction and pragmas together with new platform functions ([link](https://github.com/HyperDbg/HyperDbg/commit/9c3e0ed23b5f4bb64bd305e546dd0e86ee1910d9))
- Added interfaces to Linux port for the serial devices ([link](https://github.com/HyperDbg/HyperDbg/commit/31b514f8df40d81d44ae07a2328c02360ce488c3))
- Added platform IOCTL interface ([link](https://github.com/HyperDbg/HyperDbg/pull/619))
- Added typecast for wchar, mismatch on Linux and Windows ([link](https://github.com/HyperDbg/HyperDbg/commit/10576b064a9824ab655e7bea0e35e9556ee68ca4))
- Added missing IOCTLs for Intel PT ([link](https://github.com/HyperDbg/HyperDbg/commit/df12e9fd79851c8f378ec82a45066da510da507a))
- Added NuGet packages for Windows SDK and WDK
- Added Signal handler platform API for Linux ([link](https://github.com/HyperDbg/HyperDbg/pull/627))
- Added contribution guidelines for Linux ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/linux#readme))
### Changed
- Moved to Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/pull/626))
- Zydis and pdbex submodules are updated to VS2026
- Fix the new form of loading and unloading in the example app and PT app ([link](https://github.com/HyperDbg/HyperDbg/commit/9ad48d30dcf6b409ae86b2d08262584cd06f606e))
- Check whether the top-level hypervisor is Hyper-V and disable/enable VPIDs based on that, thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/625))
- Fix PT operation IOCTL buffer size ([link](https://github.com/HyperDbg/HyperDbg/commit/dabf132d31503843f90949f35f8dce4601d43126))
- CI/CD updated with NuGet packages for Visual Studio 2026 ([link](https://github.com/HyperDbg/HyperDbg/commit/5a0fad490124268550f955f594d1211d5c74f03d))
## [0.19.0.0-beta] - 2026-06-10
New release of the HyperDbg Debugger.
### Added
- First release of the HyperTrace module ([link](https://url.hyperdbg.org/hypertrace))
- HyperTrace now enables/disables VM-entry/VM-exit controls for Load and Save IA32_DEBUGCTL MSR
- Added Legacy LBR support to the HyperTrace module
- Added Architectural LBR support to the HyperTrace module
- Added the '!lbr' command for performing different Last Branch Record (LBR) operations ([link](https://docs.hyperdbg.org/commands/extension-commands/lbr))
- Added the '!lbrdump' command for dumping saved Last Branch Record (LBR) entries ([link](https://docs.hyperdbg.org/commands/extension-commands/lbrdump))
- Added **lbr_save()** and **lbr_print()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_save))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_print))
- Added mock application for compiling SDK for Linux
- Added '!help' alias for the '.help' command
- Added 'vm' alias for the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Added **lbr_check()** and **lbr_restore()** functions in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_check))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore))
- Added **lbr_restore_by_filter(filter)** function in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/tracing/lbr/lbr_restore_by_filter))
- Added the 'kd' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Added the 'trace' module in the 'load' command ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- Exported SDK API for detecting CPU vendors
- Initial codes for the HyperTrace project by using Intel Processor Trace (PT), thanks to [@masoudrahimi01](https://github.com/masoudrahimi01) ([link](https://github.com/HyperDbg/HyperDbg/pull/589))
- Exported SDK APIs for loading and unloading the 'kd' and the 'trace' modules
- Exported SDK APIs for starting (installing) the 'kd' driver
- Exported SDK APIs for loading/unloading all modules
- Added tests for checking PE parser in 'hyperdbg-test' project
- Added example for loading HyperDbg in VMI mode directly from libhyperdbg
- Fix action cleanup list removal in debugger events ([link](https://github.com/HyperDbg/HyperDbg/pull/601))
- Added transparent-mode evade mask selection thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/602))
- Added synthetic MSR handling thanks to [@Idov31](https://github.com/Idov31) ([link](https://github.com/HyperDbg/HyperDbg/pull/605))
- Added use of relative RSDS fixture paths when loading PDB symbols, thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/607))
### Changed
- Fix the problem of not applying the EAX index in the CPUID event extension command ([link](https://docs.hyperdbg.org/commands/extension-commands/cpuid#parameters))
- Refactoring the IOCTL parameter checks and status routines
- All basic types are now defined for Linux
- VMX instructions are ported to platform-independent files to support Linux
- All CPU-related intrinsic instructions are ported to platform-independent files to support Linux
- HyperDbg SDK now compiles on Linux (GCC) for both user-mode and kernel-mode
- Fix the 'wrmsr' command IOCTL checks by receiving output in the buffer ([link](https://docs.hyperdbg.org/commands/debugging-commands/wrmsr))
- Extensive refactoring of code base (doxygen, variables, function names)
- Building certain modules on Linux and fixing CMake files thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/592))
- Fix the '!hide' command's HyperEvade activation guard thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/593))
- Fix synchronous debugger device IOCTL handles thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/595))
- PE parser ('.pe' command) now supports richer DOS/NT/COFF/optional-header output, section bounds checking, data directory reporting, import/export parsing, TLS/debug/PDB/load-config metadata, overlay reporting, and malformed metadata warnings thanks to [@jtaw5649](https://github.com/jtaw5649) ([link](https://github.com/HyperDbg/HyperDbg/pull/598))([link](https://docs.hyperdbg.org/commands/meta-commands/.pe))
- Building the script engine module on Linux (GCC) thanks to [@maxraulea](https://github.com/maxraulea) ([link](https://github.com/HyperDbg/HyperDbg/pull/596))
- The pool manager moved from 'hyperhv' to 'hyperkd'
- The 'load' command could load all modules using a new alias 'load all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/load))
- The 'unload' command could remove all modules using two new aliases 'unload all' and 'unload remove all' ([link](https://docs.hyperdbg.org/commands/debugging-commands/unload))
- Change device handle checks with module loading status checks for IOCTLs ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
- Fix standard callbacks for the VMM module ([link](https://github.com/HyperDbg/HyperDbg/pull/610))
- Fix race condition bug within the pool manager
## [0.18.1.0] - 2026-04-09
New release of the HyperDbg Debugger.
### Added
- HyperTrace now works with HyperDbg VMM ([link](https://github.com/HyperDbg/HyperDbg/pull/568))
- Progress on implementing Last Branch Recode (LBR) ([link](https://github.com/HyperDbg/HyperDbg/commit/1dd73675e9cd78737e013ffb35bc712f385f387e))
- Applying LBR registers on the VMCS instead of the DEBUGCTL MSR ([link](https://github.com/HyperDbg/HyperDbg/commit/15f8b3cca15448acd18d7e198740464a19ce4fe2))
### Changed
- Fix the problem of the '!epthook' not finding the PML1 entry ([link](https://docs.hyperdbg.org/commands/extension-commands/epthook))
- Fix the problem of getting the PML1 entry of the target address on Intel Core Ultra processors (#567) ([link](https://github.com/HyperDbg/HyperDbg/issues/567))
- Fix the '.clang-format' formatting error
- Restructure of the HyperTrace project
- Add starting structure for supporting Intel Processor Trace (PT)
## [0.18.0.0] - 2026-02-16
New release of the HyperDbg Debugger.
### Added
- Script engine now supports writing libraries using the '#include' keyword thanks to [@xmaple555](https://github.com/xmaple555) ([link](https://docs.hyperdbg.org/commands/scripting-language/casting-and-inclusion))([link](https://github.com/HyperDbg/HyperDbg/issues/557))([link](https://github.com/HyperDbg/HyperDbg/pull/561))
- Initial codes for the HyperTrace project by using Intel Last Branch Record (LBR) and Branch Trace Store (BTS) thanks to [@harimishal1](https://github.com/harimishal1) ([link](https://github.com/HyperDbg/HyperDbg/tree/master/hyperdbg/hypertrace))
- The HyperTrace project is now linked to the hyperkd
- Initial efforts to port HyperDbg to Linux have started thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/563))
### Changed
- Fix compilation error in Zydis with the new Windows WDK ([link](https://github.com/HyperDbg/zydis/commit/e61f59332ce49f8853006573ca853e404fafdd08))
## [0.17.0.0] - 2025-11-10
New release of the HyperDbg Debugger. All credit for this release goes to [@xmaple555](https://github.com/xmaple555).
### Added
- Added 1D and 2D arrays (multidimensional arrays) in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multidimensional-array))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
- Added compound assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#compound-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
- Added multiple assignments in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/variables-and-assignments#multiple-assignment))([link](https://github.com/HyperDbg/HyperDbg/pull/554))
### Changed
- Fix bugs for interpreting 'db_pa, 'dd_pa', 'eb_pa', and 'ed_pa' keywords in the script engine ([link](https://docs.hyperdbg.org/commands/scripting-language/assumptions-and-evaluations#keywords))([link](https://github.com/HyperDbg/HyperDbg/pull/507))
- Fix variable types in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/43b0245fa11b5c73ce4cd21d8b8787b86a05f89d))
- Fix and update array index for boolean expressions in the script engine ([link](https://github.com/HyperDbg/HyperDbg/commit/ba2cec3c12c3ff45ddc0004051884983ff62a0b3))
## [0.16.0.0] - 2025-09-08
New release of the HyperDbg Debugger.
### Added
- The **!xsetbv** event command was added for handling the execution of the XSETBV instruction, thanks to HyperDbg group members ([link](https://docs.hyperdbg.org/commands/extension-commands/xsetbv))
- Display of the number of blocked context switches in the '.switch' command ([link](https://docs.hyperdbg.org/commands/meta-commands/.switch))
- Added support for step-in (the 't' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/t))
- Added support for step-over (the 'p' command) in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/p))
- Added support to show all registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
- Exported SDK API for running scripts in either the kernel debugger or the user debugger
- Added support to modify registers or a specific register in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/r))
- Added support to evaluate (run) scripts on the target thread in the user debugger ([link](https://docs.hyperdbg.org/commands/debugging-commands/eval))
- Added an indication of a thread's running or paused state to the HyperDbg signature in the user debugger ([link](https://docs.hyperdbg.org/using-hyperdbg/prerequisites/signatures))
- Added support for the '.formats' command in the user debugger ([link](https://docs.hyperdbg.org/commands/meta-commands/.formats))
- Added support for interpreting parameters based on script engine expressions in the user debugger
- Exported SDK API for evaluating expressions based on the context of the kernel debugger or the user debugger
- Added a new mechanism for showing the 'printf' and the 'print' function messages in the user debugger ([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/printf))([link](https://docs.hyperdbg.org/commands/scripting-language/functions/exports/print))
### Changed
- Non-volatile XMM registers are no longer saved/restored on VM-exit handler ([link](https://learn.microsoft.com/en-us/cpp/build/x64-software-conventions?view=msvc-170))
- Fix grammar and spelling errors throughout HyperDbg codebase ([link](https://github.com/HyperDbg/HyperDbg/pull/546))
- Relocate extension command files into their corresponding VS directory
- Fix infinite VM-exit bug for the '!monitor x' command thanks to [@unlockable](https://github.com/unlockable) ([link](https://github.com/HyperDbg/HyperDbg/pull/545))
## [0.15.0.0] - 2025-08-18
New release of the HyperDbg Debugger.
### Added
- Added the '!smi' command for performing operations related to System Management Interrupt (SMI) ([link](https://docs.hyperdbg.org/commands/extension-commands/smi))
- Export the SDK functions for SMI operations ([link](https://docs.hyperdbg.org/commands/extension-commands/smi#sdk))
- Check for Intel CET IBT (indirect branch tracking) support
- Check for Intel CET shadow stack support
- Added support to Intel CET for SYSCALL/SYSRET emulation ([link](https://docs.hyperdbg.org/commands/extension-commands/syscall))([link](https://docs.hyperdbg.org/commands/extension-commands/sysret))
### Changed
- The 'hyperhv' project now has build optimizations enabled
- Reformat VMXOFF restoring routines to restore general-purpose and XMM registers correctly before moving to the previous stack
- Fix unloading (VMXOFF) crash when restoring XMM registers
- Fix the problem with restoring XMM registers (#468) ([link](https://github.com/HyperDbg/HyperDbg/issues/468))
- Enhanced the '.pe' command to support PE Rich Headers thanks to [@Alish14](https://github.com/Alish14) ([link](https://github.com/HyperDbg/HyperDbg/pull/539))
- Updated ia32-doc to fix VMCS PL3 SSP fields ([link](https://github.com/HyperDbg/ia32-doc))
- Fix the terminating process issue of the '!syscall/!sysret' commands on 11 generation (Rocket Lake/Tiger Lake) and newer Intel processors ([link](https://github.com/HyperDbg/HyperDbg/issues/392))
- Re-enable the support for the '.start' command in the Debugger mode ([link](https://docs.hyperdbg.org/commands/meta-commands/.start))
- The '!mode' event command is now compatible with different EPT hook commands (e.g., !epthook, !epthook2, !monitor, .start, and .restart) ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
- The '!mode' command doesn't need allocating extra EPTPs ([link](https://docs.hyperdbg.org/commands/extension-commands/mode))
## [0.14.1.0] - 2025-07-27
New release of the HyperDbg Debugger.
### Changed
- Restored the previous optimization on the release builds
- Fixed the issue of not properly restoring registers after the 'CPUID' instruction
- Fixed the building issues of the user debugger with the 'bp' and the '.start' commands
## [0.14.0.0] - 2025-07-23
New release of the HyperDbg Debugger.

View file

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

View file

@ -4,7 +4,7 @@ The list provided comprises individuals who have made significant contributions
## Credits:
The attributions listed on this credits page are acknowledged without any particular order.
Just so you know the attributions listed on this credits page are acknowledged without any particular order.
- All of the [contributors](https://github.com/HyperDbg/HyperDbg/graphs/contributors)
- Sina Karvandi ([@Intel80x86](https://twitter.com/Intel80x86))
@ -24,4 +24,7 @@ The attributions listed on this credits page are acknowledged without any partic
- xmaple555 ([@xmaple555](https://github.com/xmaple555)) for contributions in HyperDbg core and the script engine
- Abbas Masoumi Gorji ([@AbbasMasoumiG](https://twitter.com/AbbasMasoumiG))
- Björn Ruytenberg ([@0Xiphorus](https://twitter.com/0Xiphorus))
- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3))
- Marcis Zarins ([@CokeTree3](https://github.com/CokeTree3)) for his works on enhancing HyperEvade project
- Artem Shishkin ([@honorary_bot](https://twitter.com/honorary_bot)) for always answering our hypervisor questions
- unrustled.jimmies for helping us debug and fix issues, and his contributions in HyperDbg
- Hari Mishal ([@harimishal1](https://github.com/harimishal1)) for his works on the hypertrace project for supporting Last Branch Record (LBR)

106
README.md
View file

@ -6,11 +6,10 @@
<a href="https://www.gnu.org/licenses/gpl-3.0"><img src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Badges/License-GPLv3-blue.svg" alt="License"></a>
</p>
# 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 an open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
**HyperDbg Debugger** is a free (as in free beer), open-source, community-driven, hypervisor-assisted, user-mode, and kernel-mode Windows debugger with a focus on using modern hardware technologies. It is a debugger designed for analyzing, fuzzing, and reversing.
You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **[Mastodon](https://infosec.exchange/@hyperdbg)** to get notified about new releases, or join any of the HyperDbg groups, where you can ask developers and open-source reversing enthusiasts for help setting up and using HyperDbg.
@ -23,12 +22,24 @@ You can follow **HyperDbg** on **[Twitter](https://twitter.com/HyperDbg)** or **
**HyperDbg** is designed with a focus on using modern hardware technologies to provide new features to the debuggers' world. It operates on top of Windows by virtualizing an already running system using Intel VT-x and EPT. This debugger aims not to use any APIs and software debugging mechanisms, but instead, it uses Second Layer Page Table (a.k.a. Extended Page Table or EPT) extensively to monitor both kernel and user executions.
<p align="center"><a href="https://hyperdbg.org/"><img align="center" width="600" height="500" src="https://raw.githubusercontent.com/HyperDbg/graphics/master/Art%20Board/Artboard%201.png" alt="HyperDbg Debugger"></a></br>
</p>
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time entirely invisible for both Windows kernel and the programs, and of course, without any limitation in size or count!
HyperDbg comes with features like hidden hooks, which are as fast as old inline hooks, but also stealth. It mimics hardware debug registers for (read & write) to a specific location, but this time invisible for both the Windows kernel and the programs, and of course, without any limitation in size or count!
Using TLB-splitting, and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
Using TLB-splitting and having features such as measuring code coverage and monitoring all mov(s) to/from memory by a function, makes HyperDbg a unique debugger.
Although it has novel features, HyperDbg tries to be as stealthy as possible. It doesnt use any debugging APIs to debug Windows or any application, so classic anti-debugging methods wont detect it. Also, it resists the exploitation of time delta methods (e.g., RDTSC/RDTSCP) to detect the presence of hypervisors, therefore making it much harder for applications, packers, protectors, malware, anti-cheat engines, etc. to discover the debugger.
## Why HyperDbg?
HyperDbg is harder to set up and use, and also requires deeper low-level system knowledge compared to traditional debuggers. However, it provides two major advantages:
1. **Full System & OS Control**
HyperDbg operates at the hypervisor level, giving you powerful capabilities that are simply not possible with classic debuggers. This allows you to leverage hardware-assisted [features](https://github.com/HyperDbg/HyperDbg?tab=readme-ov-file#unique-features) for advanced reverse engineering and debugging scenarios.
2. **Stealth & Detection Resistance**
Since HyperDbg doesn't rely on standard OS debugging APIs, it is generally much harder (though not impossible) to detect. This makes it a strong choice when working against anti-debugging protections.
These advantages open up entirely new debugging and reverse engineering techniques that go beyond what conventional debuggers can offer.
## Build & Installation
You can download the latest compiled binary files from **[releases](https://github.com/HyperDbg/HyperDbg/releases)**; otherwise, if you want to build HyperDbg, you should clone HyperDbg with the `--recursive` flag.
@ -62,26 +73,67 @@ In case you use one of **HyperDbg**'s components in your work, please consider c
<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)]
**2. [hwdbg: Debugging Hardware Like Software (EuroSec'25)](https://dl.acm.org/doi/abs/10.1145/3722041.3723101)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3722041.3723101)]
```
@article{karvandi2024reversing,
title={The Reversing Machine: Reconstructing Memory Assumptions},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and van der Kouwe, Erik},
journal={arXiv preprint arXiv:2405.00298},
year={2024}
@inproceedings{karvandi2025hwdbg,
title={hwdbg: Debugging Hardware Like Software},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Monfared, Saleh Khalaj and van der Kouwe, Erik and Slowinska, Asia},
booktitle={Proceedings of the 18th European Workshop on Systems Security},
pages={56--62},
year={2025}
}
```
**3. [HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg (DEBT'25)](https://www.jot.fm/contents/issue_2026_01/a8.html)** [[PDF](https://www.jot.fm/issues/issue_2026_01/a8.pdf)]
```
@article{ruytenberg2026hyperevade,
title={HyperEvade: Countering Anti-Debugging Techniques and Enhancing Transparency in Nested Virtualization using HyperDbg},
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina},
journal={Journal of Object Technology},
volume={25},
number={1},
pages={1--3},
year={2026},
publisher={Association Internationale pour les Technologies Objets}
}
```
**4. [Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher (EuroSys'26)](https://dl.acm.org/doi/abs/10.1145/3767295.3803583)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3767295.3803583)]
```
@inproceedings{ruytenberg2026digital,
title={Digital Hole: Bypassing Commercial Audio DRM Solutions with DReaMcatcher},
author={Ruytenberg, Bj{\"o}rn and Karvandi, Mohammad Sina and Bos, Herbert and van der Kouwe, Erik and Slowinska, Asia},
booktitle={Proceedings of the 21st European Conference on Computer Systems},
pages={484--496},
year={2026}
}
```
**5. [TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction (AsiaCCS'26)](https://dl.acm.org/doi/10.1145/3779208.3785293)** [[PDF](https://dl.acm.org/doi/pdf/10.1145/3779208.3785293)]
```
@inproceedings{karvandi2026trm,
title={TRM: An Efficient Hypervisor-Based Framework For Malware Analysis and Memory Reconstruction},
author={Karvandi, Mohammad Sina and Meghdadizanjani, Soroush and Arasteh, Sima and Monfared, Saleh Khalaj and Fallah, Mohammad K and Gorgin, Saeid and Lee, Jeong-A and Slowinska, Asia and van der Kouwe, Erik},
booktitle={Proceedings of the ACM Asia Conference on Computer and Communications Security},
pages={68--82},
year={2026}
}
```
</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.
## Unique Features
* Advanced Hypervisor-based Kernel Mode Debugger [<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/debug" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/getting-started/attach-to-hyperdbg/local-debugging" target="_blank">link</a>]
* Classic EPT Hook (Hidden Breakpoint) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/hooking-any-function" target="_blank">link</a>]
* Inline EPT Hook (Inline Hook) [<a href="https://docs.hyperdbg.org/commands/extension-commands/epthook2" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-epthook2" target="_blank">link</a>]
* Monitor Memory For R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
* Monitor Memory for R/W (Emulating Hardware Debug Registers Without Limitation) [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-monitor" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/monitoring-accesses-to-structures" target="_blank">link</a>]
* SYSCALL Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/syscall" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/intercepting-all-syscalls" target="_blank">link</a>]
* SYSRET Hook (Disable EFER & Handle #UD) [<a href="https://docs.hyperdbg.org/commands/extension-commands/sysret" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-syscall-and-sysret" target="_blank">link</a>]
* CPUID Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/cpuid" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
@ -91,15 +143,15 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* RDPMC Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/pmc" target="_blank">link</a>]
* VMCALL Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/vmcall" target="_blank">link</a>]
* Debug Registers Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/dr" target="_blank">link</a>]
* I/O Port (In Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (Out Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (IN Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioin" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* I/O Port (OUT Instruction) Hook & Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/ioout" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/triggering-special-instructions" target="_blank">link</a>]
* MMIO Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Exception (IDT < 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/exception" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
* External-Interrupt (IDT > 32) Monitor [<a href="https://docs.hyperdbg.org/commands/extension-commands/interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/features/vmm-module/design-of-exception-and-interrupt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/kernel-mode-debugging/examples/events/identifying-system-behavior" target="_blank">link</a>]
* Running Automated Scripts [<a href="https://docs.hyperdbg.org/commands/scripting-language/debugger-script" target="_blank">link</a>]
* Transparent-mode (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/hide" target="_blank">link</a>]
* Running Custom Assembly In Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
* Checking For Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
* Transparent-mode and Hyperevade Project (Anti-debugging and Anti-hypervisor Resistance) [<a href="https://docs.hyperdbg.org/tips-and-tricks/considerations/transparent-mode" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/hide" target="_blank">link</a>][<a href="https://www.vusec.net/projects/hyperevade/" target="_blank">link</a>]
* Running Custom Assembly in Both VMX-root, VMX non-root (Kernel & User) [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-an-action" target="_blank">link</a>]
* Checking for Custom Conditions [<a href="https://docs.hyperdbg.org/using-hyperdbg/prerequisites/how-to-create-a-condition" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/debugger-internals/conditions" target="_blank">link</a>]
* Process-specific & Thread-specific Debugging [<a href="https://docs.hyperdbg.org/commands/meta-commands/.process" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/meta-commands/.thread" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/using-hyperdbg/user-mode-debugging/examples/basics/switching-to-a-specific-process-or-thread" target="_blank">link</a>]
* VMX-root Compatible Message Tracing [<a href="https://docs.hyperdbg.org/design/features/vmm-module/vmx-root-mode-compatible-message-tracing" target="_blank">link</a>]
* Powerful Kernel Side Scripting Engine [<a href="https://docs.hyperdbg.org/commands/scripting-language" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/design/script-engine" target="_blank">link</a>]
@ -110,18 +162,24 @@ You can also read [this article](https://research.hyperdbg.org/debugger/kernel-d
* Various Custom Scripts [<a href="https://github.com/HyperDbg/scripts" target="_blank">link</a>]
* HyperDbg Software Development Kit (SDK) [<a href="https://docs.hyperdbg.org/using-hyperdbg/sdk" target="_blank">link</a>]
* Event Short-circuiting [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-short-circuiting" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_sc" target="_blank">link</a>]
* Tracking records of function calls and return addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
* Tracking Records of Function Calls and Return Addresses [<a href="https://docs.hyperdbg.org/commands/extension-commands/track" target="_blank">link</a>]
* Kernel-level Length Disassembler Engine (LDE) [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/diassembler/disassemble_len32" target="_blank">link</a>]
* Memory Execution Monitor & Execution Blocking [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Custom Page-fault Injection [<a href="https://docs.hyperdbg.org/commands/meta-commands/.pagein" target="_blank">link</a>]
* Different Event Calling Stages [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/event-calling-stage" target="_blank">link</a>]
* Injecting Custom Interrupts/Exceptions/Faults [<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/scripting-language/functions/events/event_inject_error_code" target="_blank">link</a>]
* Instant events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
* Detect kernel-to-user and user-to-kernel transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
* Physical memory monitoring hooks [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Instant Events in the Debugger Mode [<a href="https://docs.hyperdbg.org/tips-and-tricks/misc/instant-events" target="_blank">link</a>]
* Detecting Kernel-to-user and User-to-kernel Transitions [<a href="https://docs.hyperdbg.org/commands/extension-commands/mode" target="_blank">link</a>]
* Physical Memory Monitoring Hooks [<a href="https://docs.hyperdbg.org/commands/extension-commands/monitor" target="_blank">link</a>]
* Enumerating PCI/PCI-e Devices [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcitree" target="_blank">link</a>]
* Interpreting and Dumping PCI/PCI-e Configuration Space (CAM) [<a href="https://docs.hyperdbg.org/commands/extension-commands/pcicam" target="_blank">link</a>]
* Dumping IDT entries, I/O APIC, and Local APIC in XAPIC and X2APIC modes [<a href="https://docs.hyperdbg.org/commands/extension-commands/idt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/ioapic" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/apic" target="_blank">link</a>]
* Dumping IDT Entries, I/O APIC, and Local APIC in XAPIC and X2APIC Modes [<a href="https://docs.hyperdbg.org/commands/extension-commands/idt" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/ioapic" target="_blank">link</a>][<a href="https://docs.hyperdbg.org/commands/extension-commands/apic" target="_blank">link</a>]
* 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?
@ -133,15 +191,17 @@ You can read about the internal design of HyperDbg and its features in the [docu
</br>
## Scripts
You can write your **[scripts](https://github.com/HyperDbg/scripts)** to automate your debugging journey. **HyperDbg** has a powerful, fast, and entirely kernel-side implemented [script engine](https://docs.hyperdbg.org/commands/scripting-language).
## Contributing
Contributing to HyperDbg is super appreciated. We have made a list of potential [tasks](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md#things-to-work-on) that you might be interested in contributing towards.
If you want to contribute to HyperDbg, please read the [Contribution Guide](https://github.com/HyperDbg/HyperDbg/blob/master/CONTRIBUTING.md).
## License
**HyperDbg**, and all its submodules and repos, unless a license is otherwise specified, are licensed under **GPLv3** LICENSE.
Dependencies are licensed by their own.

View file

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

View file

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

View file

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

View file

@ -17,7 +17,7 @@
//////////////////////////////////////////////////
VOID
LoaderUninitializeLogTracer();
LoaderUninitLogTracer();
BOOLEAN
LoaderInitVmmAndReversingMachine();

View file

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

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -86,7 +89,7 @@
<TreatWarningAsError>true</TreatWarningAsError>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<Optimization>Disabled</Optimization>
<Optimization>Full</Optimization>
</ClCompile>
<Link>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
@ -110,7 +113,20 @@
<ClCompile Include="code\driver\Ioctl.c" />
<ClCompile Include="code\driver\Loader.c" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets" Condition="Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.targets'))" />
<Error Condition="!Exists('..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\hyperdbg\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props'))" />
</Target>
</Project>

View file

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

View file

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

View file

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

View file

@ -0,0 +1,583 @@
#include "pch.h"
#include <string.h>
#include <stdlib.h>
#include <dbghelp.h>
#include "../dependencies/libipt/intel-pt.h"
#include <Zydis/Zydis.h>
#pragma comment(lib, "dbghelp.lib")
static UINT64 g_ImageBase = 0;
static UINT64 g_CodeBase = 0;
static UINT64 g_CodeSize = 0;
static UINT8 * g_Code = NULL;
static int
ShowMessages(const char * Text)
{
printf("%s", Text);
return 0;
}
static int
ReadImage(uint8_t * Buffer, size_t Size, const struct pt_asid * Asid, uint64_t Ip, void * Context)
{
(void)Asid;
(void)Context;
if (g_Code == NULL || Ip < g_CodeBase || Ip >= g_CodeBase + g_CodeSize)
return -pte_nomap;
uint64_t Available = g_CodeBase + g_CodeSize - Ip;
size_t Count = (Size < Available) ? Size : (size_t)Available;
memcpy(Buffer, g_Code + (Ip - g_CodeBase), Count);
return (int)Count;
}
typedef struct _PROC_BASIC_INFO
{
LONG ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR Reserved[4];
} PROC_BASIC_INFO;
typedef LONG(NTAPI * PFN_NT_QIP)(HANDLE, ULONG, PVOID, ULONG, PULONG);
static BOOLEAN
CaptureImage(HANDLE Process, UINT64 * TextStart, UINT64 * TextEnd)
{
HMODULE Ntdll = GetModuleHandleA("ntdll.dll");
PFN_NT_QIP NtQip = Ntdll ? (PFN_NT_QIP)GetProcAddress(Ntdll, "NtQueryInformationProcess") : NULL;
PROC_BASIC_INFO Pbi = {0};
ULONG Ret = 0;
SIZE_T Got = 0;
UINT64 Base = 0;
IMAGE_DOS_HEADER Dos;
IMAGE_NT_HEADERS64 Nt;
UINT64 SectionBase;
if (NtQip == NULL || NtQip(Process, 0, &Pbi, sizeof(Pbi), &Ret) < 0 || Pbi.PebBaseAddress == NULL)
return FALSE;
if (!ReadProcessMemory(Process, (PBYTE)Pbi.PebBaseAddress + 0x10, &Base, sizeof(Base), &Got) || Base == 0)
return FALSE;
if (!ReadProcessMemory(Process, (PVOID)Base, &Dos, sizeof(Dos), &Got) || Dos.e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
if (!ReadProcessMemory(Process, (PBYTE)Base + Dos.e_lfanew, &Nt, sizeof(Nt), &Got) || Nt.Signature != IMAGE_NT_SIGNATURE)
return FALSE;
g_ImageBase = Base;
SectionBase = Base + Dos.e_lfanew + FIELD_OFFSET(IMAGE_NT_HEADERS64, OptionalHeader) + Nt.FileHeader.SizeOfOptionalHeader;
for (WORD i = 0; i < Nt.FileHeader.NumberOfSections; i++)
{
IMAGE_SECTION_HEADER Section;
if (!ReadProcessMemory(Process, (PBYTE)SectionBase + (UINT64)i * sizeof(Section), &Section, sizeof(Section), &Got))
return FALSE;
if (memcmp(Section.Name, ".text", 6) != 0)
continue;
UINT64 Start = Base + Section.VirtualAddress;
UINT64 Size = Section.Misc.VirtualSize ? Section.Misc.VirtualSize : Section.SizeOfRawData;
if (Size == 0)
return FALSE;
g_Code = (UINT8 *)malloc((size_t)Size);
if (g_Code == NULL)
return FALSE;
if (!ReadProcessMemory(Process, (PVOID)Start, g_Code, (SIZE_T)Size, &Got) || Got != Size)
{
free(g_Code);
g_Code = NULL;
return FALSE;
}
g_CodeBase = Start;
g_CodeSize = Size;
*TextStart = Start;
*TextEnd = Start + Size - 1;
return TRUE;
}
return FALSE;
}
static BOOLEAN
ResolveFunction(HANDLE Process, const char * Path, const char * Name, UINT64 * Start, UINT64 * End)
{
union
{
SYMBOL_INFO Info;
BYTE Buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
} Symbol = {0};
BOOLEAN Ok = FALSE;
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!SymInitialize(Process, NULL, FALSE))
return FALSE;
if (SymLoadModuleEx(Process, NULL, Path, NULL, (DWORD64)g_ImageBase, 0, NULL, 0) != 0)
{
Symbol.Info.SizeOfStruct = sizeof(SYMBOL_INFO);
Symbol.Info.MaxNameLen = MAX_SYM_NAME;
if (SymFromName(Process, Name, &Symbol.Info) && Symbol.Info.Address != 0)
{
*Start = Symbol.Info.Address;
*End = Symbol.Info.Address + (Symbol.Info.Size ? Symbol.Info.Size : 0x200) - 1;
Ok = TRUE;
}
}
SymCleanup(Process);
return Ok;
}
static BOOLEAN
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE Type)
{
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
Op.PtOperationType = Type;
return hyperdbg_u_pt_operation(&Op);
}
static BOOLEAN
PtFilter(UINT32 ProcessId, UINT64 Start, UINT64 End)
{
HYPERTRACE_PT_OPERATION_PACKETS Op = {};
Op.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_FILTER;
Op.FilterOptions.TraceUser = 1;
Op.EnableOptions.Pid = ProcessId;
if (End > Start)
{
Op.FilterOptions.NumAddrRanges = 1;
Op.FilterOptions.AddrRanges[0].Start = Start;
Op.FilterOptions.AddrRanges[0].End = End;
}
if (!hyperdbg_u_pt_operation(&Op))
return FALSE;
printf("[+] PT filter: cr3=0x%llx traceuser=%u ranges=%u buffer=0x%llx\n",
(unsigned long long)Op.EnableOptions.Cr3,
Op.FilterOptions.TraceUser,
Op.FilterOptions.NumAddrRanges,
(unsigned long long)Op.BufferSize);
return TRUE;
}
static const char *
PacketName(enum pt_packet_type Type)
{
switch (Type)
{
case ppt_psb: return "PSB"; case ppt_psbend: return "PSBEND"; case ppt_pad: return "PAD";
case ppt_fup: return "FUP"; case ppt_tip: return "TIP"; case ppt_tip_pge: return "TIP.PGE";
case ppt_tip_pgd: return "TIP.PGD"; case ppt_tnt_8: return "TNT8"; case ppt_tnt_64: return "TNT64";
case ppt_mode: return "MODE"; case ppt_pip: return "PIP"; case ppt_vmcs: return "VMCS";
case ppt_cbr: return "CBR"; case ppt_tsc: return "TSC"; case ppt_tma: return "TMA";
case ppt_mtc: return "MTC"; case ppt_cyc: return "CYC"; case ppt_ovf: return "OVF";
case ppt_stop: return "STOP"; case ppt_exstop: return "EXSTOP"; case ppt_mnt: return "MNT";
case ppt_ptw: return "PTW"; default: return "?";
}
}
static uint64_t
ReconstructIp(const struct pt_packet_ip * Packet, uint64_t * LastIp)
{
uint64_t Value = *LastIp;
switch (Packet->ipc)
{
case pt_ipc_update_16: Value = (Value & ~0xffffull) | (Packet->ip & 0xffffull); break;
case pt_ipc_update_32: Value = (Value & ~0xffffffffull) | (Packet->ip & 0xffffffffull); break;
case pt_ipc_update_48: Value = (Value & ~0xffffffffffffull) | (Packet->ip & 0xffffffffffffull); break;
case pt_ipc_sext_48:
Value = Packet->ip & 0xffffffffffffull;
if (Value & 0x800000000000ull)
Value |= 0xffff000000000000ull;
break;
default: Value = Packet->ip; break;
}
*LastIp = Value;
return Value;
}
static UINT64
DecodeCorePackets(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
{
struct pt_config Config;
struct pt_packet_decoder * Decoder;
UINT64 Count = 0;
uint64_t LastIp = 0;
int Status;
pt_config_init(&Config);
Config.begin = (uint8_t *)Buffer;
Config.end = (uint8_t *)Buffer + Size;
Decoder = pt_pkt_alloc_decoder(&Config);
if (Decoder == NULL)
{
printf("[-] core %u: cannot allocate packet decoder\n", Cpu);
return 0;
}
for (;;)
{
Status = pt_pkt_sync_forward(Decoder);
if (Status < 0)
break;
for (;;)
{
struct pt_packet Packet;
Status = pt_pkt_next(Decoder, &Packet, sizeof(Packet));
if (Status < 0)
break;
Count++;
switch (Packet.type)
{
case ppt_tnt_8:
case ppt_tnt_64:
printf(" %-8s %2u ", PacketName(Packet.type), Packet.payload.tnt.bit_size);
for (uint8_t Bit = 0; Bit < Packet.payload.tnt.bit_size && Bit < 64; Bit++)
putchar(((Packet.payload.tnt.payload >> (Packet.payload.tnt.bit_size - 1 - Bit)) & 1) ? 'T' : 'N');
putchar('\n');
break;
case ppt_tip:
case ppt_fup:
case ppt_tip_pge:
case ppt_tip_pgd:
if (Packet.payload.ip.ipc == pt_ipc_suppressed)
printf(" %-8s (ip suppressed)\n", PacketName(Packet.type));
else
{
uint64_t Ip = ReconstructIp(&Packet.payload.ip, &LastIp);
printf(" %-8s 0x%016llx exe+0x%llx\n",
PacketName(Packet.type), (unsigned long long)Ip, (unsigned long long)(Ip - g_ImageBase));
}
break;
case ppt_pip:
printf(" %-8s cr3=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.pip.cr3);
break;
case ppt_cbr:
//printf(" %-8s ratio=%u\n", PacketName(Packet.type), Packet.payload.cbr.ratio);
break;
case ppt_tsc:
printf(" %-8s tsc=0x%llx\n", PacketName(Packet.type), (unsigned long long)Packet.payload.tsc.tsc);
break;
default:
//printf(" %-8s\n", PacketName(Packet.type));
break;
}
}
}
pt_pkt_free_decoder(Decoder);
return Count;
}
static UINT64
DecodeCore(UINT32 Cpu, const UINT8 * Buffer, UINT64 Size)
{
struct pt_config Config;
struct pt_insn_decoder * Decoder;
struct pt_image * Image;
UINT64 Count = 0;
int Status;
pt_config_init(&Config);
Config.begin = (uint8_t *)Buffer;
Config.end = (uint8_t *)Buffer + Size;
Decoder = pt_insn_alloc_decoder(&Config);
if (Decoder == NULL)
{
printf("[-] core %u: cannot allocate instruction decoder\n", Cpu);
return 0;
}
Image = pt_insn_get_image(Decoder);
pt_image_set_callback(Image, ReadImage, NULL);
for (;;)
{
Status = pt_insn_sync_forward(Decoder);
if (Status < 0)
break;
for (;;)
{
struct pt_insn Insn;
while (Status & pts_event_pending)
{
struct pt_event Event;
Status = pt_insn_event(Decoder, &Event, sizeof(Event));
if (Status < 0)
break;
}
if (Status < 0 || (Status & pts_eos))
break;
Status = pt_insn_next(Decoder, &Insn, sizeof(Insn));
if (Status < 0)
break;
ZydisDisassembledInstruction Disasm;
ZydisMachineMode Mode = (Insn.mode == ptem_32bit) ? ZYDIS_MACHINE_MODE_LEGACY_32 : ZYDIS_MACHINE_MODE_LONG_64;
if (ZYAN_SUCCESS(ZydisDisassembleIntel(Mode, Insn.ip, Insn.raw, Insn.size, &Disasm)))
printf(" 0x%016llx exe+0x%-6llx %s\n",
(unsigned long long)Insn.ip,
(unsigned long long)(Insn.ip - g_ImageBase),
Disasm.text);
else
printf(" 0x%016llx (undecodable)\n", (unsigned long long)Insn.ip);
Count++;
}
if (Status >= 0 && (Status & pts_eos))
break;
}
pt_insn_free_decoder(Decoder);
return Count;
}
static void
RunAndTrace(const char * Path, const char * Function, BOOLEAN Packets, int PinCore)
{
STARTUPINFOA Startup = {0};
PROCESS_INFORMATION Process = {0};
HYPERTRACE_PT_MMAP_PACKETS Mmap = {0};
HYPERTRACE_PT_OPERATION_PACKETS Sizes = {0};
UINT64 TextStart = 0;
UINT64 TextEnd = 0;
UINT64 FilterStart = 0;
UINT64 FilterEnd = 0;
UINT64 Total = 0;
Startup.cb = sizeof(Startup);
if (!CreateProcessA(Path, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &Startup, &Process))
{
printf("[-] cannot launch '%s' (error 0x%x)\n", Path, GetLastError());
return;
}
printf("[+] launched '%s' (pid %u, suspended)\n", Path, Process.dwProcessId);
if (PinCore >= 0)
{
DWORD_PTR Mask = (DWORD_PTR)1 << PinCore;
if (SetProcessAffinityMask(Process.hProcess, Mask))
printf("[+] pinned target to core %d (all trace should land on this core)\n", PinCore);
else
printf("[!] could not pin to core %d (error 0x%x); running unpinned\n", PinCore, GetLastError());
}
else
{
printf("[*] target unpinned (scheduler may migrate it across cores)\n");
}
if (!CaptureImage(Process.hProcess, &TextStart, &TextEnd))
{
printf("[-] cannot read target image / .text section\n");
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
printf("[+] image base 0x%llx, .text 0x%llx-0x%llx (%llu bytes)\n",
(unsigned long long)g_ImageBase,
(unsigned long long)TextStart,
(unsigned long long)TextEnd,
(unsigned long long)g_CodeSize);
FilterStart = TextStart;
FilterEnd = TextEnd;
if (Function != NULL && ResolveFunction(Process.hProcess, Path, Function, &FilterStart, &FilterEnd)) {
printf("[+] IP filter narrowed to '%s' 0x%llx-0x%llx (%llu bytes)\n",
Function,
(unsigned long long)FilterStart,
(unsigned long long)FilterEnd,
(unsigned long long)(FilterEnd - FilterStart + 1));
}
else
{
printf("[!] IP filter: whole .text (symbol '%s' not found - build the target with a PDB)\n",
Function ? Function : "(none)");
}
if (!PtFilter(Process.dwProcessId, FilterStart, FilterEnd) ||
!PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_ENABLE))
{
printf("[-] cannot enable Intel PT\n");
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
if (!hyperdbg_u_pt_mmap(&Mmap))
{
printf("[-] pt_mmap failed\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
TerminateProcess(Process.hProcess, 1);
goto Cleanup;
}
printf("[+] PT enabled, %u per-core buffers mapped\n", Mmap.NumCpus);
printf("[*] resuming target and waiting for it to exit...\n");
ResumeThread(Process.hThread);
WaitForSingleObject(Process.hProcess, INFINITE);
printf("[+] target exited, decoding trace\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_PAUSE);
Sizes.PtOperationType = HYPERTRACE_PT_OPERATION_REQUEST_TYPE_SIZE;
if (!hyperdbg_u_pt_operation(&Sizes))
{
printf("[-] cannot query PT sizes\n");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
goto Cleanup;
}
for (UINT32 i = 0; i < Mmap.NumCpus; i++)
{
UINT32 Cpu = Mmap.Cpus[i].CpuId;
UINT64 Bytes = (Cpu < Sizes.NumCpus) ? Sizes.BytesPerCpu[Cpu] : 0;
if (Bytes == 0)
continue;
if (Bytes > Mmap.Cpus[i].Size)
Bytes = Mmap.Cpus[i].Size;
printf("\n[*] core %u: %llu bytes of trace\n", Cpu, (unsigned long long)Bytes);
Total += Packets
? DecodeCorePackets(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes)
: DecodeCore(Cpu, (const UINT8 *)(ULONG_PTR)Mmap.Cpus[i].UserVa, Bytes);
}
printf("\n[+] decoded %llu %s total\n", (unsigned long long)Total, Packets ? "packet(s)" : "instruction(s)");
PtOperation(HYPERTRACE_PT_OPERATION_REQUEST_TYPE_DISABLE);
Cleanup:
if (g_Code != NULL)
{
free(g_Code);
g_Code = NULL;
}
if (Process.hThread != NULL)
CloseHandle(Process.hThread);
if (Process.hProcess != NULL)
CloseHandle(Process.hProcess);
}
static int
LoadVmmAndTrace()
{
hyperdbg_u_set_text_message_callback((PVOID)ShowMessages);
if (!hyperdbg_u_detect_vmx_support())
{
printf("[-] VT-x (VMX) is not supported / enabled on this processor\n");
return 1;
}
printf("[*] loading HyperDbg VMM...\n");
if (hyperdbg_u_install_kd_driver() == 1 || hyperdbg_u_load_vmm() == 1)
{
printf("[-] cannot load the HyperDbg VMM\n");
return 1;
}
printf("[+] HyperDbg VMM is running\n");
printf("[*] loading HyperTrace...\n");
if ( hyperdbg_u_load_hypertrace_module() == 1)
{
printf("[-] cannot load the HyperDbg HyperTrace\n");
return 1;
}
printf("[+] HyperDbg HyperTrace is running\n");
return 0;
}
int
main2(int argc, char ** argv)
{
const char * function = "main";
BOOLEAN packets = FALSE;
int pinCore = 0;
if (argc < 2)
{
printf("HyperDbg Intel PT tracer\n");
printf("usage: %s <path-to-exe-that-exits> [function] [-p] [-c core]\n", argv[0]);
printf(" [function] symbol to IP-filter (default 'main'; pass '*' for whole .text)\n");
printf(" -p dump raw PT packets (TNT/TIP/FUP/PSB/...) instead of instructions\n");
printf(" -c core pin the target to this logical core (default 0; -1 = unpinned)\n");
return 1;
}
for (int i = 2; i < argc; i++)
{
if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--packets") == 0)
packets = TRUE;
else if (strcmp(argv[i], "-c") == 0 && i + 1 < argc)
pinCore = atoi(argv[++i]);
else if (strcmp(argv[i], "*") == 0)
function = NULL;
else
function = argv[i];
}
if (LoadVmmAndTrace() != 0)
{
return 1;
}
RunAndTrace(argv[1], function, packets, pinCore);
printf("[*] unloading HyperDbg VMM...\n");
//
// Unload the driver
//
hyperdbg_u_unload_vmm();
hyperdbg_u_unload_kd();
hyperdbg_u_stop_kd_driver();
hyperdbg_u_uninstall_kd_driver();
printf("[+] done\n");
return 0;
}

View file

@ -0,0 +1,16 @@
/**
* @file example-ipt.h
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Headers for Intel PT example
* @details
*
* @version 0.20
* @date 2026-06-13
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#pragma once
int
main2(int argc, char** argv);

View file

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

View file

@ -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,23 +101,30 @@
<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>Disabled</Optimization>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib</AdditionalDependencies>
<AdditionalLibraryDirectories>$(LibIptDir)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(SolutionDir)build\bin\$(Configuration)\libhyperdbg.lib;$(SolutionDir)libraries\zydis\user\Zydis.lib;$(SolutionDir)libraries\zydis\user\Zycore.lib;$(SolutionDir)libraries\libipt\libipt.lib</AdditionalDependencies>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
</Link>
<PostBuildEvent>
<Command>
</Command>
<Message>
</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View file

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

View file

@ -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'])

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

@ -1 +1 @@
Subproject commit 6ef251e3e58c759fda025c186ef0f44c556c14c1
Subproject commit 2bc5284e04ff862220def160517bc72baf3d1a03

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

View file

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

View file

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

View file

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

View file

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

View file

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

View 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))
{
//

View file

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

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

View file

@ -1,7 +1,7 @@
/**
* @file test-parser.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Perfrom test on command parser
* @brief Perform test on command parser
* @details
* @version 0.11
* @date 2024-08-11
@ -11,132 +11,132 @@
*/
#include "pch.h"
typedef char ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as a char**
typedef CHAR ** CHAR_PTR_PTR; // Define CHAR_PTR_PTR as CHAR**
/**
* @brief Create an array of strings from a vector of strings
* @param testCases The vector of strings to copy
* @param TestCases The vector of strings to copy
*
* @return A pointer to the array of strings
*/
CHAR_PTR_PTR
createTestCaseArray(const std::vector<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,42 +306,42 @@ TestCommandParser()
//
// Parse the test cases from the file
//
auto testCases = parseTestCases(filePath);
auto TestCases = ParseTestCases(FilePath);
//
// Perfom testing test cases with parsed file
// Perform testing test cases with parsed file
//
cout << "Perfom testing test cases with parsed file:" << endl;
cout << "Perform testing test cases with parsed file:" << endl;
//
// 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;
}

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

View file

@ -1,7 +1,7 @@
/**
* @file test-semanitc-scripts.cpp
* @file test-semantic-scripts.cpp
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Perfrom test on semantic scripts
* @brief Perform test on semantic scripts
* @details
* @version 0.11
* @date 2024-08-16
@ -21,7 +21,7 @@ namespace fs = std::filesystem;
* @return VOID
*/
VOID
ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
ReadDirectoryAndTestSemanticTestCases(const CHAR * ScriptSemanticPath)
{
//
// Iterate through the directory
@ -38,7 +38,7 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
//
// Get the file path
//
std::string filePath = entry.path().string();
std::string FilePath = entry.path().string();
//
// Output the file name
@ -48,10 +48,10 @@ ReadDirectoryAndTestSemanticTestcases(const char * ScriptSemanticPath)
//
// Open the file and read its contents
//
std::ifstream file(filePath);
if (file.is_open())
std::ifstream File(FilePath);
if (File.is_open())
{
std::string content((std::istreambuf_iterator<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

View file

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

View file

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

View file

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

View file

@ -18,5 +18,11 @@
BOOLEAN
TestCommandParser();
BOOLEAN
TestPeParser();
BOOLEAN
TestCodeViewRsdsParser();
BOOLEAN
TestSemanticScripts();

View file

@ -21,14 +21,14 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset>v145</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<SpectreMitigation>false</SpectreMitigation>
@ -63,8 +63,8 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
@ -85,13 +85,13 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>$(SolutionDir)\include;$(SolutionDir)dependencies;$(ProjectDir);$(SolutionDir)libhyperdbg;$(SolutionDir)symbol-parser;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<TreatWarningAsError>true</TreatWarningAsError>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>Disabled</Optimization>
<Optimization>MaxSpeed</Optimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -103,23 +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">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='release|x64'">Create</PrecompiledHeader>
</ClCompile>
<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>

View file

@ -21,14 +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="pch.cpp">
<Filter>code</Filter>
</ClCompile>
<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>
@ -44,30 +59,48 @@
<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="pch.h">
<Filter>header</Filter>
</ClInclude>
<ClInclude Include="header\namedpipe.h">
<Filter>header</Filter>
</ClInclude>
<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>
<ClInclude Include="header\hwdbg-tests.h">
<Filter>header</Filter>
</ClInclude>
<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>

View file

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

View file

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32602.215
# Visual Studio Version 18
VisualStudioVersion = 18.7.11911.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyperdbg-cli", "hyperdbg-cli\hyperdbg-cli.vcxproj", "{FBCBBBAD-4EAE-469E-827F-F59FE9E7375B}"
ProjectSection(ProjectDependencies) = postProject
@ -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}

View file

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

View file

@ -11,6 +11,49 @@
*/
#include "pch.h"
#if ActivateHyperEvadeProject != TRUE
/**
* @brief Handle The triggered hook on KiSystemCall64 system call handler
* when the Transparency mode is disabled
*
* @param Regs The virtual processor's state of registers
* @return VOID
*/
VOID
TransparentHandleSystemCallHook(GUEST_REGS * Regs)
{
UNREFERENCED_PARAMETER(Regs);
}
/**
* @brief Callback function to handle returns from the syscall
* when the Transparency mode is disabled
*
* @param Regs The virtual processor's state of registers
* @param ProcessId The process id of the thread
* @param ThreadId The thread id of the thread
* @param Context The context of the caller
* @param Params The (optional) parameters of the caller
*
* @return VOID
*/
VOID
TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
UINT32 ProcessId,
UINT32 ThreadId,
UINT64 Context,
SYSCALL_CALLBACK_CONTEXT_PARAMS * Params)
{
UNREFERENCED_PARAMETER(Regs);
UNREFERENCED_PARAMETER(ProcessId);
UNREFERENCED_PARAMETER(ThreadId);
UNREFERENCED_PARAMETER(Context);
UNREFERENCED_PARAMETER(Params);
}
#else // ActivateHyperEvadeProject != TRUE
/**
* @brief Handle The triggered hook on KiSystemCall64 system call handler
* when the Transparency mode is enabled
@ -233,7 +276,7 @@ TransparentHandleNtQuerySystemInformationSyscall(GUEST_REGS * Regs)
*
* @details Returns an allocated tagged memory pointer which needs to be freed with PlatformMemFreePool()
*
* @param virtPtr A pointer to a guest virutal memory address, containing a OBJECT_ATTRIBUTES structure
* @param virtPtr A pointer to a guest virtual memory address, containing a OBJECT_ATTRIBUTES structure
* @return PVOID Pointer to an allocated tagged memory pool, which needs to be freed with PlatformMemFreePool()
*/
PVOID
@ -668,7 +711,7 @@ TransparentHandleNtQueryValueKeySyscall(GUEST_REGS * Regs)
&ContextParams);
//
// Clean-up and return to guest exection
// Clean-up and return to guest execution
//
PlatformMemFreePool(NameBuf);
return;
@ -783,7 +826,7 @@ TransparentHandleNtEnumerateKeySyscall(GUEST_REGS * Regs)
* it is possible to still detect that some tampering was done from the user space
*
* @param Ptr The pointer to a valid read/writable SYSTEM_MODULE_INFORMATION memory buffer
* @param VirualAddress A pointer to a user-mode virual address
* @param VirtualAddress A pointer to a user-mode virtual address
* @param BufferSize Size of the user-mode buffer
*
* @return BOOLEAN
@ -800,11 +843,11 @@ TransparentHandleModuleInformationQuery(PVOID Ptr, UINT64 VirtualAddress, UINT32
//
for (UINT16 i = 0; i < StructBuf->Count; i++)
{
PCHAR path = (PCHAR)ModuleList[i].FullPathName;
PCHAR Path = (PCHAR)ModuleList[i].FullPathName;
for (UINT16 j = 0; j < (sizeof(HV_DRIVER) / sizeof(HV_DRIVER[0])); j++)
{
if (strstr(path, HV_DRIVER[j]))
if (strstr(Path, HV_DRIVER[j]))
{
//
// If a module file name matches, remove the entry from the list by shifting it forward by one entry
@ -912,9 +955,9 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
//
// Loop through the known list of identifiable hypervisor related processes
//
for (UINT16 i = 0; i < (sizeof(HV_Processes) / sizeof(HV_Processes[0])); i++)
for (UINT16 i = 0; i < (sizeof(HV_PROCESSES) / sizeof(HV_PROCESSES[0])); i++)
{
if (!_wcsnicmp(ImageName, HV_Processes[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
if (!_wcsnicmp(ImageName, HV_PROCESSES[i], (CurStructBuf.ImageName.Length) / sizeof(WCHAR)))
{
//
// If the name matches, bypass it by increasing the previous entries .nextEntryOffset value
@ -965,7 +1008,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
}
//
// If the current entry didnt match any process names, move forward
// If the current entry did not match any process names, move forward
//
if (!MatchFound)
{
@ -988,7 +1031,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
}
//
// Zero out the matching entry, so that its data doesnt remain in memory
// Zero out the matching entry, so that its data doesn't remain in memory
//
if (MatchFound)
{
@ -1015,7 +1058,7 @@ TransparentHandleProcessInformationQuery(SYSCALL_CALLBACK_CONTEXT_PARAMS * Param
/**
* @brief Handle the request for SystemFirmwareTableInformation
*
* @param ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
* @param Ptr The pointer to a valid read/writable SYSTEM_FIRMWARE_TABLE_INFORMATION memory buffer
* @param BufMaxSize The size of the allocated user-mode buffer
* @param BufSizePtr A pointer to a ULONG field containing the size of the written data
*
@ -1041,14 +1084,14 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
if (BufSize > BufMaxSize)
{
//
// NOTE: might need zeroing the memory if the kernel did infact write to the pointer
// NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
//
return 0;
}
//
// If the buffer size is too big, we cant do any mitigations with the current implementation an it exceeds
// the size of an EPT page, risking curruption when allocating the copy buffer space in root-mode.
// If the buffer size is too big, we can't do any mitigations with the current implementation and it exceeds
// the size of an EPT page, risking corruption when allocating the copy buffer space in root-mode.
//
if (BufMaxSize > PAGE_SIZE / 2)
{
@ -1124,9 +1167,9 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
//
ULONG MatchedStringLen = (ULONG)strlen(HV_FIRM_NAMES[i]);
ULONG oldLength = StructBuf->TableBufferLength;
ULONG OldLength = StructBuf->TableBufferLength;
ULONG NewStringSize = oldLength - MatchedStringLen + NewSubstringSize;
ULONG NewStringSize = OldLength - MatchedStringLen + NewSubstringSize;
//
// Check if the buffer size allows the modification, in case of expansion
@ -1143,7 +1186,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
//
// Update the required buffer size for the next call
//
BufSize = (BufSize - oldLength) + NewStringSize;
BufSize = (BufSize - OldLength) + NewStringSize;
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(BufSizePtr, &BufSize, sizeof(ULONG));
//
@ -1164,7 +1207,7 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
// Move the data after the matched string forward
// and replace the identified hypervisor string with the genuine one
//
memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, oldLength - MatchedStringLen - MatchOffset);
memmove((PVOID)(StringBuf + MatchOffset + NewSubstringSize), (PVOID)MatchEnd, OldLength - MatchedStringLen - MatchOffset);
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, NewSubstringSize);
StructBuf->TableBufferLength = NewStringSize;
@ -1192,11 +1235,11 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
}
/**
* @brief Replace occurances of a hypervisor specific strings with legitimate vendor strings in a provided buffer
* @brief Replace occurrences of a hypervisor specific strings with legitimate vendor strings in a provided buffer
*
* @param Params Set transparent callback params that contain:
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
in OptionalParam3 max size in bytes of the allocatec buffer
in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @param DataOffset Offset in bytes from OptionalParam2 to the start of the WCHAR data string
@ -1208,8 +1251,8 @@ TransparentHandleFirmwareInformationQuery(UINT64 Ptr, UINT32 BufMaxSize, UINT64
UINT64
TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS * Params, ULONG DataOffset, ULONG DataLenOffset)
{
PVOID Buf = NULL;
BOOL PoolAlloc = FALSE;
PVOID Buf = NULL;
BOOLEAN PoolAlloc = FALSE;
//
// Check that the user provided pointers are safe to read from
@ -1231,7 +1274,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
if (BufSize > Params->OptionalParam3 || BufSize == 0)
{
//
// NOTE: might need zeroing the memory if the kernel did infact write to the pointer
// NOTE: might need zeroing the memory if the kernel did in fact write to the pointer
//
return 0;
@ -1291,7 +1334,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// SPOOFS PCI device ID's(in the registry), This might be implemented in other ways that are not part of this implementation
//
WORD Idx = TRANSPARENT_GENUINE_VENDOR_STRING_INDEX % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
WORD Idx = g_TransparentGenuineVendorStringIndex % (sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[0]));
NewVendorString = TRANSPARENT_LEGIT_DEVICE_ID_VENDOR_STRINGS_WCHAR[Idx];
}
@ -1307,23 +1350,23 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Obtain the replacement vendor name string, randomized when the transparency mode was enabled
//
NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[TRANSPARENT_GENUINE_VENDOR_STRING_INDEX];
NewVendorString = TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[g_TransparentGenuineVendorStringIndex];
}
//
// Obtain the lengths of all the strings and substring
//
ULONG tempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
ULONG TempSize = (ULONG)wcslen(NewVendorString) * sizeof(WCHAR);
ULONG MatchedStringLen = (ULONG)wcslen(HV_REGKEYS[i]) * sizeof(WCHAR);
ULONG oldLength = *((PBYTE)Buf + DataLenOffset);
ULONG OldLength = *((PBYTE)Buf + DataLenOffset);
ULONG NewStringSize = oldLength - MatchedStringLen + tempSize;
ULONG NewStringSize = OldLength - MatchedStringLen + TempSize;
//
// Check if the buffer size allows the modification, in case of expansion
//
if (BufSize - MatchedStringLen + tempSize > Params->OptionalParam3)
if (BufSize - MatchedStringLen + TempSize > Params->OptionalParam3)
{
//
// If adding the new string exceeds the user allocated size,
@ -1335,7 +1378,7 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Update the required buffer size for the next call
//
BufSize = (tempSize - MatchedStringLen) + oldLength;
BufSize = (TempSize - MatchedStringLen) + OldLength;
g_Callbacks.MemoryMapperWriteMemorySafeOnTargetProcess(Params->OptionalParam4, &BufSize, sizeof(ULONG));
//
@ -1356,15 +1399,15 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
//
// Move the data after the matched string forward
//
memmove((PVOID)(StringBuf + MatchOffset + (tempSize / sizeof(WCHAR))), (PVOID)MatchEnd, oldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
memmove((PVOID)(StringBuf + MatchOffset + (TempSize / sizeof(WCHAR))), (PVOID)MatchEnd, OldLength - MatchedStringLen - (MatchOffset * sizeof(WCHAR)));
//
// Replace the identified hypervisor string with the genuine one, if needed
//
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, tempSize);
memcpy((PVOID)MatchStart, (PVOID)NewVendorString, TempSize);
*(PULONG)((PBYTE)Buf + DataLenOffset) = NewStringSize;
BufSize = BufSize - MatchedStringLen + tempSize;
BufSize = BufSize - MatchedStringLen + TempSize;
//
// Write the changes back to the user buffers
@ -1399,11 +1442,11 @@ TransparentReplaceVendorStringFromBufferWChar(SYSCALL_CALLBACK_CONTEXT_PARAMS *
}
//
// An error occured while performing the mitigations, the user buffer might be left unmodified
// An error occurred while performing the mitigations, the user buffer might be left unmodified
//
ReturnWithError:
LogInfo("A call for to read a registry entry, which could contain hypervisor specific data, was intercepted but the mitigations failed");
LogInfo("The caller process recieved the results in this virtual address: %llx", Params->OptionalParam2);
LogInfo("The caller process received the results in this virtual address: %llx", Params->OptionalParam2);
if (Buf != NULL)
{
@ -1420,7 +1463,7 @@ ReturnWithError:
* @param Params The set transparent callback params that contain:
in OptionalParam1 the KEY_VALUE_INFORMATION_CLASS enum value
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
in OptionalParam3 max size in bytes of the allocatec buffer
in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @return UINT64
@ -1497,12 +1540,12 @@ TransparentCallbackHandleAfterNtQueryValueKeySyscall(SYSCALL_CALLBACK_CONTEXT_PA
}
/**
* @brief Callback function to handle the returns from the NtQueryValueKey syscall
* @brief Callback function to handle the returns from the NtEnumerateKey syscall
*
* @param Params The set transparent callback params that contain:
in OptionalParam1 the KEY_VALUE_INFORMATION_CLASS enum value
in OptionalParam2 a pointer to a valid read/writable memory buffer that contains both, a WCHAR string and its length in bytes
in OptionalParam3 max size in bytes of the allocatec buffer
in OptionalParam3 max size in bytes of the allocated buffer
in OptionalParam4 a pointer to a ULONG containing current size of the buffer
*
* @return UINT64
@ -1857,10 +1900,10 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
//
// Handle the return code modification after NtNtQueryValueKey system call
//
// NOTE: The transparent mitigation will replace all occurances of a hypervisor vendor string in the registry
// NOTE: The transparent mitigation will replace all occurrences of a hypervisor vendor string in the registry
// key data to a randomized real hardware vendor string, no matter the meaning of the key,
// This can cause some keys to illogical data, for example,
// a disk drive ID having a vendor string of ASUS even though(as far as I know) ASUS doesnt produce storage devices.
// This can cause some keys to produce illogical data, for example,
// a disk drive ID having a vendor string of ASUS even though (as far as I know) ASUS doesn't produce storage devices.
//
else if (Context == g_SystemCallNumbersInformation.SysNtQueryValueKey)
{
@ -1927,3 +1970,4 @@ TransparentCallbackHandleAfterSyscall(GUEST_REGS * Regs,
Params->OptionalParam4);
}
}
#endif // ActivateHyperEvadeProject != TRUE

View file

@ -1,6 +1,7 @@
/**
/**
* @file Transparency.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @author jtaw5649
* @brief Try to hide the debugger from anti-debugging and anti-hypervisor methods
* @details
* @version 0.1
@ -14,8 +15,8 @@
/**
* @brief Hide debugger on transparent-mode (activate transparent-mode)
*
* @param HyperevadeCallbacks
* @param TransparentModeRequest
* @param HyperevadeCallbacks Pointer to the HyperEvade callbacks structure
* @param TransparentModeRequest Pointer to the transparent debugger mode request
*
* @return BOOLEAN
*/
@ -23,6 +24,19 @@ BOOLEAN
TransparentHideDebugger(HYPEREVADE_CALLBACKS * HyperevadeCallbacks,
DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE * TransparentModeRequest)
{
UINT32 EvadeMask = TransparentModeRequest->EvadeMask;
if (EvadeMask == 0)
{
EvadeMask = TRANSPARENT_EVADE_MASK_DEFAULT;
}
if ((EvadeMask & ~TRANSPARENT_EVADE_MASK_ALL) != 0)
{
TransparentModeRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_HIDE_OR_UNHIDE_DEBUGGER;
return FALSE;
}
//
// Check if any of the required callbacks are NULL
//
@ -54,17 +68,20 @@ TransparentHideDebugger(HYPEREVADE_CALLBACKS * Hyperevade
RtlCopyBytes(&g_SystemCallNumbersInformation,
&TransparentModeRequest->SystemCallNumbersInformation,
sizeof(SYSTEM_CALL_NUMBERS_INFORMATION));
#if ActivateHyperEvadeProject == TRUE
//
// Choose a random genuine vendor string to replace hypervisor vendor data
//
TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = TransparentGetRand() %
(sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
g_TransparentGenuineVendorStringIndex = TransparentGetRand() %
(sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR) / sizeof(TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[0]));
#endif
//
// Enable the transparent mode
//
g_TransparentMode = TRUE;
g_TransparentEvadeMask = EvadeMask;
TransparentModeRequest->EvadeMask = EvadeMask;
TransparentModeRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
//
@ -92,7 +109,8 @@ TransparentUnhideDebugger()
//
// Disable the transparent-mode
//
g_TransparentMode = FALSE;
g_TransparentMode = FALSE;
g_TransparentEvadeMask = 0;
return TRUE;
}
@ -114,7 +132,7 @@ TransparentGetRand()
UINT64 Tsc;
UINT32 Rand;
Tsc = __rdtsc();
Tsc = CpuReadTsc();
Rand = Tsc & 0xffff;
return Rand;
@ -124,7 +142,7 @@ TransparentGetRand()
* @brief Add name or process id of the target process to the list
* of processes that HyperDbg should apply transparent-mode on them
*
* @param Measurements
* @param Measurements Pointer to the debugger hide and transparent mode request structure
* @return BOOLEAN
*/
BOOLEAN
@ -188,8 +206,8 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
//
// Move the process name string to the end of the buffer
//
RtlCopyBytes((void *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
(const void *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
RtlCopyBytes((VOID *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
(CONST VOID *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
Measurements->LengthOfProcessName);
//
@ -598,7 +616,7 @@ TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_M
// //
// // Save the current time
// //
// CurrrentTime = __rdtscp(&Aux);
// CurrrentTime = CpuReadTscp(&Aux);
//
// //
// // Save time of vm-exit on each logical processor separately

View file

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

View file

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

View file

@ -81,17 +81,17 @@ typedef struct _SYSTEM_PROCESS_INFORMATION
* @brief SSDT structure
*
*/
typedef struct _SSDTStruct
typedef struct _SSDT_STRUCT
{
LONG * pServiceTable;
PVOID pCounterTable;
LONG * ServiceTable;
PVOID CounterTable;
#ifdef _WIN64
UINT64 NumberOfServices;
#else
ULONG NumberOfServices;
#endif
PCHAR pArgumentTable;
} SSDTStruct, *PSSDTStruct;
PCHAR ArgumentTable;
} SSDT_STRUCT, *PSSDT_STRUCT;
/**
* @brief Module entry
@ -128,7 +128,7 @@ typedef NTSTATUS(NTAPI * ZWQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTSTATUS(*NtCreateFileOrig)
NTSTATUS(*g_NtCreateFileOrig)
(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
@ -150,7 +150,7 @@ NTSTATUS(*NtCreateFileOrig)
* @brief A variable holding the randomly chosen index for the genuine vendor list.
* This is used for transparent vendor spoofing
*/
static WORD TRANSPARENT_GENUINE_VENDOR_STRING_INDEX = 0;
static WORD g_TransparentGenuineVendorStringIndex = 0;
/**
* @brief System call numbers information
@ -161,6 +161,8 @@ SYSTEM_CALL_NUMBERS_INFORMATION g_SystemCallNumbersInformation;
// Constants //
//////////////////////////////////////////////////
#if ActivateHyperEvadeProject == TRUE
/**
* @brief A list of windows processes, for which to ignore systemcall requests
* when the transparency mode is enabled
@ -239,7 +241,7 @@ static const PWCHAR TRANSPARENT_LEGIT_VENDOR_STRINGS_WCHAR[] = {
* @brief A list of common Hypervisor specific process executables
*
*/
static const PWCH HV_Processes[] = {
static const PWCH HV_PROCESSES[] = {
L"hyperdbg-cli.exe",
L"vboxservice.exe",
L"vmsrvc.exe",
@ -360,7 +362,7 @@ static const PWCH HV_FILES[] = {
// HyperDbg Files
//
L"hyperhv",
L"hyperkd"
L"hyperkd",
L"hyperlog",
L"libhyperdbg",
@ -557,11 +559,12 @@ static const PWCH HV_REGKEYS[] = {
};
//
// @brief A list of registry keys which might contain hypervisor vendor information in their data
//
// NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
//
/**
* @brief A list of registry keys which might contain hypervisor vendor information in their data
*
* @details NOTE: This is not a complete list, there are a lot of generic keys that also can have the identifiable data
*
*/
static const PWCH TRANSPARENT_DETECTABLE_REGISTRY_KEYS[] = {
L"AcpiData",
L"SMBiosData",
@ -609,6 +612,8 @@ static const PCHAR HV_FIRM_NAMES[] = {
};
#endif
//////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////

View file

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

View file

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

View file

@ -19,9 +19,9 @@
//
// Environment headers
//
#include "platform/kernel/header/Environment.h"
#include "platform/general/header/Environment.h"
#ifdef ENV_WINDOWS
#ifdef HYPERDBG_ENV_WINDOWS
//
// Windows defined functions
@ -30,7 +30,7 @@
# include <ntstrsafe.h>
# include <Windef.h>
#endif // ENV_WINDOWS
#endif // HYPERDBG_ENV_WINDOWS
//
// Scope definitions
@ -61,13 +61,14 @@
//
// Hyperlog headers
//
#include "components/interface/HyperLogCallback.h"
#include "components/callback/header/HyperLogCallback.h"
#include "SDK/imports/kernel/HyperDbgHyperLogIntrinsics.h"
//
// Platform independent headers
//
#include "platform/kernel/header/Mem.h"
#include "platform/kernel/header/PlatformMem.h"
#include "platform/kernel/header/PlatformIntrinsics.h"
//
// Hyperevade Callbacks

View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.x64.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.x64.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.CPP.10.0.28000.1839\build\native\Microsoft.Windows.SDK.cpp.props')" />
<Import Project="..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props" Condition="Exists('..\packages\Microsoft.Windows.WDK.x64.10.0.28000.1839\build\native\Microsoft.Windows.WDK.x64.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug|x64">
<Configuration>debug</Configuration>
@ -27,7 +30,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release|x64'" Label="Configuration">
@ -36,7 +39,7 @@
<PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<DriverType>KMDF</DriverType>
<DriverTargetPlatform>Universal</DriverTargetPlatform>
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
<Driver_SpectreMitigation>false</Driver_SpectreMitigation>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@ -87,7 +90,7 @@
<PrecompiledHeader>Create</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>Disabled</Optimization>
<Optimization>Full</Optimization>
</ClCompile>
<Link>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
@ -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>

View file

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

View file

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

View file

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

View file

@ -68,4 +68,18 @@ AsmReloadIdtr ENDP
;------------------------------------------------------------------------
; AsmReadSsp ( );
AsmReadSsp PROC
; Save the current SSP to a memory location
rdsspq rax ; Save SSP to memory at the current location (stack pointer)
; Return from the function
ret
AsmReadSsp ENDP
;------------------------------------------------------------------------
END

View file

@ -1,7 +1,8 @@
PUBLIC AsmVmexitHandler
PUBLIC AsmVmxoffRestoreXmmRegs
EXTERN VmxVmexitHandler:PROC
EXTERN VmxVmresume:PROC
EXTERN VmxPerformVmresume:PROC
EXTERN VmxReturnStackPointerForVmxoff:PROC
EXTERN VmxReturnInstructionPointerForVmxoff:PROC
@ -15,32 +16,42 @@ AsmVmexitHandler PROC
; irql less or equal as it doesn't exist, so we just put some extra space avoid
; these kind of errors
pushfq
; --------------- Save RFLAGS ----------------
pushfq ; Save the flags register (RFLAGS)
; ------------ Save XMM Registers ------------
; 16 Byte * 16 Byte = 256 + 4 = 260 (0x104 == 0x110 but let's align it to have better performance)
sub rsp, 0110h
movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
movaps xmmword ptr [rsp+010h], xmm1
movaps xmmword ptr [rsp+020h], xmm2
movaps xmmword ptr [rsp+030h], xmm3
movaps xmmword ptr [rsp+040h], xmm4
movaps xmmword ptr [rsp+050h], xmm5
;
; ;;;;;;;;;;;; 16 Byte * 16 Byte = 256 + 4 = 260 (0x106 == 0x110 but let's align it to have better performance) ;;;;;;;;;;;;
; sub rsp, 0110h
; As per Microsoft ABI documentation, the following registers are nonvolatile
; So, MSVC compiler will save them on the stack if they are used in the function
; Thus, for the sake of performance, we comment them out
;
; movaps xmmword ptr [rsp+000h], xmm0 ; each xmm register 128 bit (16 Byte)
; movaps xmmword ptr [rsp+010h], xmm1
; movaps xmmword ptr [rsp+020h], xmm2
; movaps xmmword ptr [rsp+030h], xmm3
; movaps xmmword ptr [rsp+040h], xmm4
; movaps xmmword ptr [rsp+050h], xmm5
; movaps xmmword ptr [rsp+060h], xmm6
; movaps xmmword ptr [rsp+070h], xmm7
; movaps xmmword ptr [rsp+080h], xmm8
; movaps xmmword ptr [rsp+090h], xmm9
; movaps xmmword ptr [rsp+0a0h], xmm10
; movaps xmmword ptr [rsp+0b0h], xmm11
; movaps xmmword ptr [rsp+0c0h], xmm12
; movaps xmmword ptr [rsp+0d0h], xmm13
; movaps xmmword ptr [rsp+0e0h], xmm14
; movaps xmmword ptr [rsp+0f0h], xmm15
; stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
;
;---------------------------------------------
; movaps xmmword ptr [rsp+060h], xmm6
; movaps xmmword ptr [rsp+070h], xmm7
; movaps xmmword ptr [rsp+080h], xmm8
; movaps xmmword ptr [rsp+090h], xmm9
; movaps xmmword ptr [rsp+0a0h], xmm10
; movaps xmmword ptr [rsp+0b0h], xmm11
; movaps xmmword ptr [rsp+0c0h], xmm12
; movaps xmmword ptr [rsp+0d0h], xmm13
; movaps xmmword ptr [rsp+0e0h], xmm14
; movaps xmmword ptr [rsp+0f0h], xmm15
stmxcsr dword ptr [rsp+0100h] ; MxCsr is 4 Byte
; ------ Save General-purpose Registers ------
push r15
push r14
@ -58,21 +69,28 @@ AsmVmexitHandler PROC
push rdx
push rcx
push rax
; ----------- Call VM-exit Handler -----------
mov rcx, rsp ; Fast call argument to PGUEST_REGS
sub rsp, 020h ; Free some space for Shadow Section
call VmxVmexitHandler
add rsp, 020h ; Restore the state
cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
cmp al, 1 ; Check whether we have to turn off VMX or Not (the result is in RAX)
je AsmVmxoffHandler
; ----------- Restore XMM Registers ----------
RestoreState:
pop rax
pop rcx
pop rdx
pop rbx
pop rbp ; rsp
pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@ -86,71 +104,92 @@ RestoreState:
pop r15
; ------------ Restore XMM Registers ------------
movaps xmm0, xmmword ptr [rsp+000h]
movaps xmm1, xmmword ptr [rsp+010h]
movaps xmm2, xmmword ptr [rsp+020h]
movaps xmm3, xmmword ptr [rsp+030h]
movaps xmm4, xmmword ptr [rsp+040h]
movaps xmm5, xmmword ptr [rsp+050h]
;
; movaps xmm0, xmmword ptr [rsp+000h]
; movaps xmm1, xmmword ptr [rsp+010h]
; movaps xmm2, xmmword ptr [rsp+020h]
; movaps xmm3, xmmword ptr [rsp+030h]
; movaps xmm4, xmmword ptr [rsp+040h]
; movaps xmm5, xmmword ptr [rsp+050h]
; movaps xmm6, xmmword ptr [rsp+060h]
; movaps xmm7, xmmword ptr [rsp+070h]
; movaps xmm8, xmmword ptr [rsp+080h]
; movaps xmm9, xmmword ptr [rsp+090h]
; movaps xmm10, xmmword ptr [rsp+0a0h]
; movaps xmm11, xmmword ptr [rsp+0b0h]
; movaps xmm12, xmmword ptr [rsp+0c0h]
; movaps xmm13, xmmword ptr [rsp+0d0h]
; movaps xmm14, xmmword ptr [rsp+0e0h]
; movaps xmm15, xmmword ptr [rsp+0f0h]
; As per Microsoft ABI documentation, the following registers are nonvolatile
; So, MSVC compiler will save them on the stack if they are used in the function
; Thus, for the sake of performance, we comment them out
;
; ldmxcsr dword ptr [rsp+0100h]
;
; add rsp, 0110h
; movaps xmm6, xmmword ptr [rsp+060h]
; movaps xmm7, xmmword ptr [rsp+070h]
; movaps xmm8, xmmword ptr [rsp+080h]
; movaps xmm9, xmmword ptr [rsp+090h]
; movaps xmm10, xmmword ptr [rsp+0a0h]
; movaps xmm11, xmmword ptr [rsp+0b0h]
; movaps xmm12, xmmword ptr [rsp+0c0h]
; movaps xmm13, xmmword ptr [rsp+0d0h]
; movaps xmm14, xmmword ptr [rsp+0e0h]
; movaps xmm15, xmmword ptr [rsp+0f0h]
ldmxcsr dword ptr [rsp+0100h]
add rsp, 0110h
; --------------- Restore RFLAGS ---------------
popfq ; Restore the flags register (RFLAGS)
; ----------------------------------------------
popfq
sub rsp, 0100h ; to avoid error in future functions
jmp VmxVmresume
jmp VmxPerformVmresume
AsmVmexitHandler ENDP
;------------------------------------------------------------------------
AsmVmxoffRestoreXmmRegs PROC
; ------------ Restore XMM Registers ------------
movaps xmm0, xmmword ptr [rcx+000h]
movaps xmm1, xmmword ptr [rcx+010h]
movaps xmm2, xmmword ptr [rcx+020h]
movaps xmm3, xmmword ptr [rcx+030h]
movaps xmm4, xmmword ptr [rcx+040h]
movaps xmm5, xmmword ptr [rcx+050h]
;
; As per Microsoft ABI documentation, the following registers are nonvolatile
; So, MSVC compiler will save them on the stack if they are used in the function
; Thus, for the sake of performance, we comment them out
;
; movaps xmm6, xmmword ptr [rcx+060h]
; movaps xmm7, xmmword ptr [rcx+070h]
; movaps xmm8, xmmword ptr [rcx+080h]
; movaps xmm9, xmmword ptr [rcx+090h]
; movaps xmm10, xmmword ptr [rcx+0a0h]
; movaps xmm11, xmmword ptr [rcx+0b0h]
; movaps xmm12, xmmword ptr [rcx+0c0h]
; movaps xmm13, xmmword ptr [rcx+0d0h]
; movaps xmm14, xmmword ptr [rcx+0e0h]
; movaps xmm15, xmmword ptr [rcx+0f0h]
ldmxcsr dword ptr [rcx+0100h]
ret
AsmVmxoffRestoreXmmRegs ENDP
;------------------------------------------------------------------------
AsmVmxoffHandler PROC
sub rsp, 020h ; shadow space
call VmxReturnStackPointerForVmxoff
add rsp, 020h ; remove for shadow space
mov [rsp+88h], rax ; now, rax contains rsp
sub rsp, 020h ; shadow space
call VmxReturnInstructionPointerForVmxoff
add rsp, 020h ; remove for shadow space
mov rdx, rsp ; save current rsp
mov rbx, [rsp+88h] ; read rsp again
mov rsp, rbx
push rax ; push the return address as we changed the stack, we push
; it to the new stack
mov rsp, rdx ; restore previous rsp
sub rbx,08h ; we push sth, so we have to add (sub) +8 from previous stack
; also rbx already contains the rsp
mov [rsp+88h], rbx ; move the new pointer to the current stack
; ------ Restore General-purpose Registers ------
RestoreState:
pop rax
pop rcx
pop rdx
pop rbx
pop rbp ; rsp
pop rbp ; rsp
pop rbp
pop rsi
pop rdi
@ -163,34 +202,40 @@ RestoreState:
pop r14
pop r15
; ------------ Restore XMM Registers ------------
;
; movaps xmm0, xmmword ptr [rsp+000h]
; movaps xmm1, xmmword ptr [rsp+010h]
; movaps xmm2, xmmword ptr [rsp+020h]
; movaps xmm3, xmmword ptr [rsp+030h]
; movaps xmm4, xmmword ptr [rsp+040h]
; movaps xmm5, xmmword ptr [rsp+050h]
; movaps xmm6, xmmword ptr [rsp+060h]
; movaps xmm7, xmmword ptr [rsp+070h]
; movaps xmm8, xmmword ptr [rsp+080h]
; movaps xmm9, xmmword ptr [rsp+090h]
; movaps xmm10, xmmword ptr [rsp+0a0h]
; movaps xmm11, xmmword ptr [rsp+0b0h]
; movaps xmm12, xmmword ptr [rsp+0c0h]
; movaps xmm13, xmmword ptr [rsp+0d0h]
; movaps xmm14, xmmword ptr [rsp+0e0h]
; movaps xmm15, xmmword ptr [rsp+0f0h]
;
; ldmxcsr dword ptr [rsp+0100h]
;
; add rsp, 0110h
; ------------- Pass over XMM Regs -------------
; XMM registers are restored by AsmVmxoffRestoreXmmRegs
; Size of XMM registers are 110 bytes but we also remove the RFLAGS register (+8)
; so we have 118 bytes to remove from the stack
add rsp, 0118h
; ------------ Get Stack Pointer ---------------
sub rsp, 020h ; shadow space
call VmxReturnStackPointerForVmxoff
add rsp, 020h ; remove for shadow space
push rax ; save the current rsp, we will restore it later
; ------------ Get Instruction Pointer ---------
sub rsp, 020h ; shadow space
call VmxReturnInstructionPointerForVmxoff
add rsp, 020h ; remove for shadow space
pop rsp ; restore rsp
push rax ; push the instruction pointer
; ----------------------------------------------
popfq
pop rsp ; restore rsp
; There might be some registers that are modified by above CALLs,
; but here we do not care about them since we are also in a function,
; so the caller do not expect us to preserve these volatile registers
ret ; jump back to where we called Vmcall
xor rax, rax ; clear RAX to indicate VMXOFF was successful (VMCALL Status)
ret ; jump back to where we called Vmcall
AsmVmxoffHandler ENDP

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -73,7 +73,7 @@ CompatibilityCheckGetX86VirtualAddressWidth()
UINT32
CompatibilityCheckGetX86PhysicalAddressWidth()
{
int Regs[4];
INT32 Regs[4];
CommonCpuidInstruction(CPUID_ADDR_WIDTH, 0, Regs);
@ -83,6 +83,36 @@ CompatibilityCheckGetX86PhysicalAddressWidth()
return (Regs[0] & 0x0ff);
}
/**
* @brief Check if the processor supports CET IBT
*
* @return BOOLEAN
*/
BOOLEAN
CompatibilityCheckCetShadowStackSupport()
{
INT32 Regs[4];
CommonCpuidInstruction(7, 0, Regs);
return (BOOLEAN)((Regs[2] & (1 << 7)) != 0); // // CpuInfo[3] is ECX
}
/**
* @brief Check for Intel CET IBT support
*
* @return BOOLEAN
*/
BOOLEAN
CompatibilityCheckCetIbtSupport()
{
INT32 Regs[4];
CommonCpuidInstruction(7, 0, Regs);
return (BOOLEAN)((Regs[3] & (1 << 20)) != 0); // CpuInfo[3] is EDX
}
/**
* @brief Check for mode-based execution
*
@ -96,7 +126,7 @@ CompatibilityCheckModeBasedExecution()
// the "enable PML" VM - execution control
//
UINT32 SecondaryProcBasedVmExecControls = HvAdjustControls(IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG,
IA32_VMX_PROCBASED_CTLS2);
IA32_VMX_PROCBASED_CTLS2);
if (SecondaryProcBasedVmExecControls & IA32_VMX_PROCBASED_CTLS2_MODE_BASED_EXECUTE_CONTROL_FOR_EPT_FLAG)
{
@ -172,6 +202,16 @@ CompatibilityCheckPerformChecks()
//
g_CompatibilityCheck.ModeBasedExecutionSupport = CompatibilityCheckModeBasedExecution();
//
// Check Intel CET IBT support
//
g_CompatibilityCheck.CetIbtSupport = CompatibilityCheckCetIbtSupport();
//
// Check Intel CET shadow stack support
//
g_CompatibilityCheck.CetShadowStackSupport = CompatibilityCheckCetShadowStackSupport();
//
// Check PML support
//

View file

@ -33,9 +33,9 @@ DirtyLoggingInitialize()
//
//
// When PML is active each write that sets a dirty flag for EPT also generates an entry in an inmemory log,
// When PML is active each write that sets a dirty flag for EPT also generates an entry in an in-memory log,
// reporting the guest-physical address of the write (aligned to 4 KBytes)
// When the log is full, a VM exit occurs, notifying the VMM.A VMM can monitor the number of pages modified
// When the log is full, a VM exit occurs, notifying the VMM. A VMM can monitor the number of pages modified
// by each thread by specifying an available set of log entries
//
@ -53,7 +53,7 @@ DirtyLoggingInitialize()
// the 4 - KByte aligned physical address of the page - modification log.The page modification
// log comprises 512 64 - bit entries
//
for (size_t i = 0; i < ProcessorsCount; i++)
for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_GuestState[i].PmlBufferAddress == NULL)
{
@ -65,7 +65,7 @@ DirtyLoggingInitialize()
//
// Allocation failed
//
for (size_t j = 0; j < ProcessorsCount; j++)
for (SIZE_T j = 0; j < ProcessorsCount; j++)
{
if (g_GuestState[j].PmlBufferAddress != NULL)
{
@ -119,12 +119,12 @@ DirtyLoggingEnable(VIRTUAL_MACHINE_STATE * VCpu)
// LogInfo("PML Buffer Address = %llx", PmlPhysAddr);
__vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, PmlPhysAddr);
//
// Clear the PML index
//
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
//
// If the "enable PML" VM-execution control is 1 and bit 6 of EPT pointer (EPTP)
@ -160,12 +160,12 @@ DirtyLoggingDisable(VIRTUAL_MACHINE_STATE * VCpu)
//
// Clear the address
//
__vmx_vmwrite(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
VmxVmwrite64(VMCS_CTRL_PML_ADDRESS, NULL64_ZERO);
//
// Clear the PML index
//
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, 0x0);
VmxVmwrite64(VMCS_GUEST_PML_INDEX, 0x0);
//
// Disable PML Enable bit
@ -196,7 +196,7 @@ DirtyLoggingUninitialize()
//
// Free the allocated pool buffers
//
for (size_t i = 0; i < ProcessorsCount; i++)
for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
if (g_GuestState[i].PmlBufferAddress != NULL)
{
@ -218,7 +218,7 @@ DirtyLoggingHandlePageModificationLog(VIRTUAL_MACHINE_STATE * VCpu)
//
// The guest-physical address of the access is written to the page-modification log
//
for (size_t i = 0; i < PML_ENTITY_NUM; i++)
for (SIZE_T i = 0; i < PML_ENTITY_NUM; i++)
{
LogInfo("Address : %llx", VCpu->PmlBufferAddress[i]);
}
@ -284,7 +284,7 @@ DirtyLoggingFlushPmlBuffer(VIRTUAL_MACHINE_STATE * VCpu)
//
// reset PML index
//
__vmx_vmwrite(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
VmxVmwrite64(VMCS_GUEST_PML_INDEX, PML_ENTITY_NUM - 1);
return TRUE;
}

View file

@ -80,22 +80,22 @@ EptHookReservePreallocatedPoolsForEptHooks(UINT32 Count)
// Request pages to be allocated for converting 2MB to 4KB pages
// Each core needs its own splitting page-tables
//
PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT), Count * ProcessorsCount, SPLIT_2MB_PAGING_TO_4KB_PAGE);
//
// Request pages to be allocated for paged hook details
//
PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL), Count, TRACKING_HOOKED_PAGES);
//
// Request pages to be allocated for Trampoline of Executable hooked pages
//
PoolManagerRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
PoolManagerCallbackRequestAllocation(MAX_EXEC_TRAMPOLINE_SIZE, Count, EXEC_TRAMPOLINE);
//
// Request pages to be allocated for detour hooked pages details
//
PoolManagerRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
PoolManagerCallbackRequestAllocation(sizeof(HIDDEN_HOOKS_DETOUR_DETAILS), Count, DETOUR_HOOK_DETAILS);
}
/**
@ -120,16 +120,16 @@ EptHookAllocateExtraHookingPagesForMemoryMonitorsAndExecEptHooks(UINT32 Count)
// Request pages to be allocated for converting 2MB to 4KB pages
// Each core needs its own splitting page-tables
//
PoolManagerRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
Count * ProcessorsCount,
SPLIT_2MB_PAGING_TO_4KB_PAGE);
PoolManagerCallbackRequestAllocation(sizeof(VMM_EPT_DYNAMIC_SPLIT),
Count * ProcessorsCount,
SPLIT_2MB_PAGING_TO_4KB_PAGE);
//
// Request pages to be allocated for paged hook details
//
PoolManagerRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
Count,
TRACKING_HOOKED_PAGES);
PoolManagerCallbackRequestAllocation(sizeof(EPT_HOOKED_PAGE_DETAIL),
Count,
TRACKING_HOOKED_PAGES);
}
/**
@ -150,7 +150,6 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
EPT_PML1_ENTRY ChangedEntry;
SIZE_T PhysicalBaseAddress;
PVOID VirtualTarget;
PVOID TargetBuffer;
UINT64 TargetAddressInFakePageContent;
PEPT_PML1_ENTRY TargetPage;
PEPT_HOOKED_PAGE_DETAIL HookedPage;
@ -200,7 +199,7 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the detail of hooked page to keep track of it
//
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
if (!HookedPage)
{
@ -275,26 +274,18 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Split the 2MB page-table of each core to 4KB page-table
//
for (size_t i = 0; i < ProcessorsCount; i++)
for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// Set target buffer, request buffer from pool manager,
// we also need to allocate new page to replace the current page
// We need to split the large page to 4KB page using pre-allocated pools
//
TargetBuffer = (PVOID)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
if (!TargetBuffer)
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_PRE_ALLOCATED_BUFFER_IS_EMPTY);
return FALSE;
}
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TargetBuffer, PhysicalBaseAddress))
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
//
// Here also other previous pools should be specified, but we forget it for now
//
LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES);
@ -311,8 +302,11 @@ EptHookCreateHookPage(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
if (!TargetPage)
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
PoolManagerCallbackFreePool((UINT64)HookedPage);
//
// Here also other previous pools should be specified, but we forget it for now
//
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_FAILED_TO_GET_PML1_ENTRY_OF_TARGET_ADDRESS);
return FALSE;
@ -913,7 +907,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
//
// Allocate some executable memory for the trampoline
//
Hook->Trampoline = (CHAR *)PoolManagerRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
Hook->Trampoline = (CHAR *)PoolManagerCallbackRequestPool(EXEC_TRAMPOLINE, TRUE, MAX_EXEC_TRAMPOLINE_SIZE);
if (!Hook->Trampoline)
{
@ -962,7 +956,7 @@ EptHookInstructionMemory(PEPT_HOOKED_PAGE_DETAIL Hook,
// function that changes the original function and if our structure is no ready after this
// function then we probably see BSOD on other cores
//
DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
DetourHookDetails = (HIDDEN_HOOKS_DETOUR_DETAILS *)PoolManagerCallbackRequestPool(DETOUR_HOOK_DETAILS, TRUE, sizeof(HIDDEN_HOOKS_DETOUR_DETAILS));
DetourHookDetails->HookedFunctionAddress = TargetFunction;
DetourHookDetails->ReturnAddress = Hook->Trampoline;
@ -1007,7 +1001,6 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
EPT_PML1_ENTRY ChangedEntry;
SIZE_T PhysicalBaseAddress;
PVOID AlignedTargetVaOrPa;
PVOID TargetBuffer;
PVOID TargetAddress;
PVOID HookFunction;
UINT64 TargetAddressInSafeMemory;
@ -1111,7 +1104,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
// Save the detail of hooked page to keep track of it
//
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
HookedPage = (EPT_HOOKED_PAGE_DETAIL *)PoolManagerCallbackRequestPool(TRACKING_HOOKED_PAGES, TRUE, sizeof(EPT_HOOKED_PAGE_DETAIL));
if (!HookedPage)
{
@ -1162,7 +1155,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
if (!HookedPage->StartOfTargetPhysicalAddress)
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@ -1190,7 +1183,7 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
if (!HookedPage->EndOfTargetPhysicalAddress)
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_INVALID_ADDRESS);
return FALSE;
@ -1251,34 +1244,25 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
if (!EptHookInstructionMemory(HookedPage, ProcessCr3, TargetAddress, (PVOID)TargetAddressInSafeMemory, HookFunction))
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerCallbackFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_COULD_NOT_BUILD_THE_EPT_HOOK);
return FALSE;
}
}
for (size_t i = 0; i < ProcessorsCount; i++)
for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// Set target buffer, request buffer from pool manager,
// we also need to allocate new page to replace the current page
// We need to split the large page to 4KB page using pre-allocated pools
//
TargetBuffer = (PVOID)PoolManagerRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
if (!TargetBuffer)
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TRUE, PhysicalBaseAddress))
{
PoolManagerFreePool((UINT64)HookedPage);
VmmCallbackSetLastError(DEBUGGER_ERROR_PRE_ALLOCATED_BUFFER_IS_EMPTY);
return FALSE;
}
if (!EptSplitLargePage(g_GuestState[i].EptPageTable, TargetBuffer, PhysicalBaseAddress))
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
PoolManagerCallbackFreePool((UINT64)HookedPage);
//
// Here also other previous pools should be specified, but we forget it for now
//
LogDebugInfo("Err, could not split page for the address : 0x%llx", PhysicalBaseAddress);
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_COULD_NOT_SPLIT_THE_LARGE_PAGE_TO_4KB_PAGES);
return FALSE;
@ -1294,8 +1278,11 @@ EptHookPerformPageHookMonitorAndInlineHook(VIRTUAL_MACHINE_STATE * VCpu,
//
if (!TargetPage)
{
PoolManagerFreePool((UINT64)HookedPage);
PoolManagerFreePool((UINT64)TargetBuffer); // Here also other previous pools should be specified, but we forget it for now
PoolManagerCallbackFreePool((UINT64)HookedPage);
//
// Here also other previous pools should be specified, but we forget it for now
//
VmmCallbackSetLastError(DEBUGGER_ERROR_EPT_FAILED_TO_GET_PML1_ENTRY_OF_TARGET_ADDRESS);
return FALSE;
@ -1875,7 +1862,7 @@ EptHookRemoveEntryAndFreePoolFromEptHook2sDetourList(UINT64 Address)
//
// Free the pool in next ioctl
//
if (!PoolManagerFreePool((UINT64)CurrentHookedDetails))
if (!PoolManagerCallbackFreePool((UINT64)CurrentHookedDetails))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}
@ -1977,7 +1964,7 @@ EptHookUnHookSingleAddressDetoursAndMonitor(PEPT_HOOKED_PAGE_DETAIL
// we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
if (!PoolManagerFreePool((UINT64)HookedEntry))
if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
return FALSE;
@ -2082,7 +2069,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// is the HookedEntry that should be remove (not the first one as it has the
// correct PreviousByte)
//
for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
{
if (HookedEntry->BreakpointAddresses[i] == VirtualAddress)
{
@ -2126,7 +2113,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
if (!PoolManagerFreePool((UINT64)HookedEntry))
if (!PoolManagerCallbackFreePool((UINT64)HookedEntry))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}
@ -2175,7 +2162,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// in the array, then we'll ignore setting the previous bit as previous bit might
// be modified for the previous command
//
for (size_t j = 0; j < HookedEntry->CountOfBreakpoints; j++)
for (SIZE_T j = 0; j < HookedEntry->CountOfBreakpoints; j++)
{
if (HookedEntry->BreakpointAddresses[j] == VirtualAddress)
{
@ -2202,7 +2189,7 @@ EptHookUnHookSingleAddressHiddenBreakpoint(PEPT_HOOKED_PAGE_DETAIL H
// all addresses to a lower array index (because one entry is
// missing and might) be in the middle of the array
//
for (size_t j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
for (SIZE_T j = i /* IndexToRemove */; j < HookedEntry->CountOfBreakpoints - 1; j++)
{
HookedEntry->BreakpointAddresses[j] = HookedEntry->BreakpointAddresses[j + 1];
HookedEntry->PreviousBytesOnBreakpointAddresses[j] = HookedEntry->PreviousBytesOnBreakpointAddresses[j + 1];
@ -2287,7 +2274,7 @@ EptHookPerformUnHookSingleAddress(UINT64 VirtualAdd
//
// It's a hidden breakpoint
//
for (size_t i = 0; i < CurrEntity->CountOfBreakpoints; i++)
for (SIZE_T i = 0; i < CurrEntity->CountOfBreakpoints; i++)
{
if (CurrEntity->BreakpointAddresses[i] == VirtualAddress)
{
@ -2498,7 +2485,7 @@ EptHookUnHookAll()
// As we are in vmx-root here, we add the hooked entry to the list
// of pools that will be deallocated on next IOCTL
//
if (!PoolManagerFreePool((UINT64)CurrEntity))
if (!PoolManagerCallbackFreePool((UINT64)CurrEntity))
{
LogError("Err, something goes wrong, the pool not found in the list of previously allocated pools by pool manager");
}

View file

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

View file

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

View file

@ -1,4 +1,4 @@
/**
/**
* @file EferHook.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Implementation of the functions related to the EFER Syscall Hook
@ -38,7 +38,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Reading IA32_VMX_BASIC_MSR
//
VmxBasicMsr.AsUInt = __readmsr(IA32_VMX_BASIC);
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
//
// Read previous VM-Entry and VM-Exit controls
@ -46,7 +46,7 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
VmxVmread32P(VMCS_CTRL_VMENTRY_CONTROLS, &VmEntryControls);
VmxVmread32P(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, &VmExitControls);
MsrValue.AsUInt = __readmsr(IA32_EFER);
MsrValue.AsUInt = CpuReadMsr(IA32_EFER);
if (EnableEFERSyscallHook)
{
@ -55,17 +55,17 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Set VM-Entry controls to load EFER
//
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls | IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
//
// Set VM-Exit controls to save EFER
//
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls | IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
//
// Set the GUEST EFER to use this value as the EFER
//
__vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
//
// also, we have to set exception bitmap to cause vm-exit on #UDs
@ -79,23 +79,23 @@ SyscallHookConfigureEFER(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN EnableEFERSyscall
//
// Set VM-Entry controls to load EFER
//
__vmx_vmwrite(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~VM_ENTRY_LOAD_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, HvAdjustControls(VmEntryControls & ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS));
//
// Set VM-Exit controls to save EFER
//
__vmx_vmwrite(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~VM_EXIT_SAVE_IA32_EFER, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, HvAdjustControls(VmExitControls & ~IA32_VMX_EXIT_CTLS_SAVE_IA32_EFER_FLAG, VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS));
//
// Set the GUEST EFER to use this value as the EFER
//
__vmx_vmwrite(VMCS_GUEST_EFER, MsrValue.AsUInt);
VmxVmwrite64(VMCS_GUEST_EFER, MsrValue.AsUInt);
//
// Because we're not save or load EFER on vm-exits so
// we have to set it manually
//
__writemsr(IA32_EFER, MsrValue.AsUInt);
CpuWriteMsr(IA32_EFER, MsrValue.AsUInt);
//
// unset the exception to not cause vm-exit on #UDs
@ -119,11 +119,13 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 MsrValue;
UINT64 GuestRip;
UINT64 GuestRflags;
UINT64 Ssp;
IA32_U_CET_REGISTER UcetMsr;
//
// Reading guest's RIP
//
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
//
// Reading instruction length
@ -133,29 +135,47 @@ SyscallHookEmulateSYSCALL(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's Rflags
//
__vmx_vmread(VMCS_GUEST_RFLAGS, &GuestRflags);
VmxVmread64P(VMCS_GUEST_RFLAGS, &GuestRflags);
//
// Save the address of the instruction following SYSCALL into RCX and then
// load RIP from IA32_LSTAR.
//
MsrValue = __readmsr(IA32_LSTAR);
MsrValue = CpuReadMsr(IA32_LSTAR);
VCpu->Regs->rcx = GuestRip + InstructionLength;
GuestRip = MsrValue;
__vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
//
// Save RFLAGS into R11 and then mask RFLAGS using IA32_FMASK
//
MsrValue = __readmsr(IA32_FMASK);
MsrValue = CpuReadMsr(IA32_FMASK);
VCpu->Regs->r11 = GuestRflags;
GuestRflags &= ~(MsrValue | X86_FLAGS_RF);
__vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
//
// Perform emulation of Intel CET (Shadow stacks)
//
if (g_CompatibilityCheck.CetShadowStackSupport)
{
UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
//
// If the shadow stack is enabled, we have to save the current
//
if (UcetMsr.ShStkEn)
{
VmxVmread64P(VMCS_GUEST_SSP, &Ssp);
CpuWriteMsr(IA32_PL3_SSP, Ssp);
VmxVmwrite64(VMCS_GUEST_SSP, 0);
}
}
//
// Load the CS and SS selectors with values derived from bits 47:32 of IA32_STAR
//
MsrValue = __readmsr(IA32_STAR);
MsrValue = CpuReadMsr(IA32_STAR);
Cs.Selector = (UINT16)((MsrValue >> 32) & ~3); // STAR[47:32] & ~RPL3
Cs.Base = 0; // flat segment
Cs.Limit = (UINT32)~0; // 4GB limit
@ -185,23 +205,42 @@ SyscallHookEmulateSYSRET(VIRTUAL_MACHINE_STATE * VCpu)
UINT64 MsrValue;
UINT64 GuestRip;
UINT64 GuestRflags;
UINT64 Ssp;
IA32_U_CET_REGISTER UcetMsr;
//
// Load RIP from RCX
//
GuestRip = VCpu->Regs->rcx;
__vmx_vmwrite(VMCS_GUEST_RIP, GuestRip);
VmxVmwrite64(VMCS_GUEST_RIP, GuestRip);
//
// Load RFLAGS from R11. Clear RF, VM, reserved bits
//
GuestRflags = (VCpu->Regs->r11 & ~(X86_FLAGS_RF | X86_FLAGS_VM | X86_FLAGS_RESERVED_BITS)) | X86_FLAGS_FIXED;
__vmx_vmwrite(VMCS_GUEST_RFLAGS, GuestRflags);
VmxVmwrite64(VMCS_GUEST_RFLAGS, GuestRflags);
//
// Restore user-mode SPP
//
if (g_CompatibilityCheck.CetShadowStackSupport)
{
UcetMsr.AsUInt = CpuReadMsr(IA32_U_CET);
//
// If the shadow stack is enabled, we have to restore the current
//
if (UcetMsr.ShStkEn)
{
Ssp = CpuReadMsr(IA32_PL3_SSP);
VmxVmwrite64(VMCS_GUEST_SSP, Ssp);
}
}
//
// SYSRET loads the CS and SS selectors with values derived from bits 63:48 of IA32_STAR
//
MsrValue = __readmsr(IA32_STAR);
MsrValue = CpuReadMsr(IA32_STAR);
Cs.Selector = (UINT16)(((MsrValue >> 48) + 16) | 3); // (STAR[63:48]+16) | 3 (* RPL forced to 3 *)
Cs.Base = 0; // Flat segment
Cs.Limit = (UINT32)~0; // 4GB limit
@ -234,7 +273,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's RIP
//
__vmx_vmread(VMCS_GUEST_RIP, &Rip);
VmxVmread64P(VMCS_GUEST_RIP, &Rip);
if (g_IsUnsafeSyscallOrSysretHandling)
{
@ -272,9 +311,9 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
//
// if ((GuestCr3.Flags & PCID_MASK) != PCID_NONE)
OriginalCr3 = __readcr3();
OriginalCr3 = CpuReadCr3();
__writecr3(GuestCr3.Flags);
CpuWriteCr3(GuestCr3.Flags);
//
// Read the memory
@ -313,7 +352,7 @@ SyscallHookHandleUD(VIRTUAL_MACHINE_STATE * VCpu)
return FALSE;
}
__writecr3(OriginalCr3);
CpuWriteCr3(OriginalCr3);
if (InstructionBuffer[0] == 0x0F &&
InstructionBuffer[1] == 0x05)

View file

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

View file

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

View file

@ -116,19 +116,6 @@ DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu)
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// Check if attaching is for command dispatching in user debugger
// or a regular CPUID
//
if (g_Callbacks.UdCheckForCommand != NULL && g_Callbacks.UdCheckForCommand())
{
//
// It's a thread command for user debugger, no need to run the
// actual CPUID instruction and change the registers
//
return;
}
//
// As the context to event trigger, we send the eax before the cpuid
// so that the debugger can both read the eax as it's now changed by
@ -183,6 +170,73 @@ DispatchEventCpuid(VIRTUAL_MACHINE_STATE * VCpu)
}
}
/**
* @brief Handling debugger functions related to XSETBV events
*
* @param VCpu The virtual processor's state
* @return VOID
*/
VOID
DispatchEventXsetbv(VIRTUAL_MACHINE_STATE * VCpu)
{
UINT64 Context;
VMM_CALLBACK_TRIGGERING_EVENT_STATUS_TYPE EventTriggerResult;
BOOLEAN PostEventTriggerReq = FALSE;
//
// As the context to event trigger, we send the ecx (XCR index) before the xsetbv
// so that the debugger can both read the ecx as it contains the XCR index
// and also can modify the results
//
if (g_TriggerEventForXsetbvs)
{
//
// Adjusting the core context (save ECX for the debugger)
//
Context = VCpu->Regs->rcx & 0xffffffff;
//
// Triggering the pre-event
//
EventTriggerResult = VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_PRE_EVENT_EMULATION,
(PVOID)Context,
&PostEventTriggerReq,
VCpu->Regs);
//
// Check whether we need to short-circuiting event emulation or not
//
if (EventTriggerResult != VMM_CALLBACK_TRIGGERING_EVENT_STATUS_SUCCESSFUL_IGNORE_EVENT)
{
//
// Handle the XSETBV event in the case of triggering event
//
VmxHandleXsetbv(VCpu);
}
//
// Check for the post-event triggering needs
//
if (PostEventTriggerReq)
{
VmmCallbackTriggerEvents(XSETBV_INSTRUCTION_EXECUTION,
VMM_CALLBACK_CALLING_STAGE_POST_EVENT_EMULATION,
(PVOID)Context,
NULL,
VCpu->Regs);
}
}
else
{
//
// Otherwise and if there is no event, we should handle the XSETBV
// normally
//
VmxHandleXsetbv(VCpu);
}
}
/**
* @brief Handling debugger functions related to RDTSC/RDTSCP events
*
@ -326,7 +380,7 @@ DispatchEventMode(VIRTUAL_MACHINE_STATE * VCpu, DEBUGGER_EVENT_MODE_TYPE TargetM
//
// If the thread is intercepted, we should not trigger the event
// Being here means that the thread should be handled by the user-mode debugger
//
// ou
// LogInfo("Thread Id: %x, process Id: %x is intercepted by user-mode debugger - RIP: %llx",
// PsGetCurrentThreadId(),
@ -657,13 +711,9 @@ DispatchEventMov2DebugRegs(VIRTUAL_MACHINE_STATE * VCpu)
BOOLEAN PostEventTriggerReq = FALSE;
//
// Handle access to debug registers, if we should not ignore it, it is
// because on detecting thread scheduling we ignore the hardware debug
// registers modifications
// Check to see if we should ignore handling the mov 2 debug registers or not
//
if (g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId != NULL &&
g_Callbacks.KdQueryDebuggerQueryThreadOrProcessTracingDetailsByCoreId(VCpu->CoreId,
DEBUGGER_THREAD_PROCESS_TRACING_INTERCEPT_CLOCK_DEBUG_REGISTER_INTERCEPTION))
if (DebuggingCallbackIgnoreHandlingMov2DebugRegs(VCpu->CoreId))
{
return;
}
@ -796,7 +846,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
// Check if we're waiting for an NMI on this core and if the guest is NOT in
// a instrument step-in ('i' command) routine
//
if (!VCpu->RegisterBreakOnMtf &&
if (!VCpu->InstrumentationStepInMtf &&
VmxBroadcastNmiHandler(VCpu, FALSE))
{
return;
@ -831,7 +881,7 @@ DispatchEventException(VIRTUAL_MACHINE_STATE * VCpu)
//
// So, we'll ignore the injection of Exception in this case
//
if (VCpu->RegisterBreakOnMtf)
if (VCpu->InstrumentationStepInMtf)
{
return;
}
@ -920,10 +970,11 @@ DispatchEventExternalInterrupts(VIRTUAL_MACHINE_STATE * VCpu)
if ((/* VCpu->CoreId == 0 && */ InterruptExit.Vector == CLOCK_INTERRUPT) ||
(VCpu->CoreId != 0 && InterruptExit.Vector == IPI_INTERRUPT))
{
if (g_Callbacks.DebuggerCheckProcessOrThreadChange != NULL)
{
g_Callbacks.DebuggerCheckProcessOrThreadChange(VCpu->CoreId);
}
//
// Calling the callback to trigger on clock and IPI events
// This is usually used for detecting changes to processes and threads
//
DebuggingCallbackTriggerOnClockAndIpiEvents(VCpu->CoreId);
}
//

View file

@ -63,29 +63,42 @@ VmFuncChangeIgnoreOneMtfState(UINT32 CoreId, BOOLEAN Set)
}
/**
* @brief Register for break in the case of an MTF
* @brief Set instrumentation step in MTF (used for single stepping with MTF)
*
* @param CoreId Target core's ID
*
* @return VOID
*/
VOID
VmFuncRegisterMtfBreak(UINT32 CoreId)
VmFuncSetInstrumentationStepInState(UINT32 CoreId)
{
g_GuestState[CoreId].RegisterBreakOnMtf = TRUE;
g_GuestState[CoreId].InstrumentationStepInMtf = TRUE;
}
/**
* @brief Unregister for break in the case of an MTF
* @brief Unset instrumentation step in MTF (used for single stepping with MTF)
*
* @param CoreId Target core's ID
*
* @return VOID
*/
VOID
VmFuncUnRegisterMtfBreak(UINT32 CoreId)
VmFuncUnsetInstrumentationStepInState(UINT32 CoreId)
{
g_GuestState[CoreId].RegisterBreakOnMtf = FALSE;
g_GuestState[CoreId].InstrumentationStepInMtf = FALSE;
}
/**
* @brief Query instrumentation step in MTF state
*
* @param CoreId Target core's ID
*
* @return BOOLEAN
*/
BOOLEAN
VmFuncQueryInstrumentationStepInState(UINT32 CoreId)
{
return g_GuestState[CoreId].InstrumentationStepInMtf;
}
/**
@ -115,25 +128,57 @@ VmFuncSetRflagTrapFlag(BOOLEAN Set)
/**
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
*
* @param CoreId target core id
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetLoadDebugControls(BOOLEAN Set)
VmFuncSetLoadDebugControls(UINT32 CoreId, BOOLEAN Set)
{
HvSetLoadDebugControls(Set);
HvSetLoadDebugControls(&g_GuestState[CoreId], Set);
}
/**
* @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
*
* @param CoreId target core id
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetLoadGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
{
HvSetLoadGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
}
/**
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
*
* @param CoreId target core id
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetSaveDebugControls(BOOLEAN Set)
VmFuncSetSaveDebugControls(UINT32 CoreId, BOOLEAN Set)
{
HvSetSaveDebugControls(Set);
HvSetSaveDebugControls(&g_GuestState[CoreId], Set);
}
/**
* @brief Set CLEAR GUEST IA32_LBR_CTL on Vm-exit controls
*
* @param CoreId target core id
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetClearGuestIa32LbrCtl(UINT32 CoreId, BOOLEAN Set)
{
HvSetClearGuestIa32LbrCtl(&g_GuestState[CoreId], Set);
}
/**
@ -389,6 +434,211 @@ VmFuncSetRip(UINT64 Rip)
HvSetRip(Rip);
}
/**
* @brief Get the guest state of IA32_DEBUGCTL
*
* @return UINT64
*/
UINT64
VmFuncGetDebugctl()
{
return HvGetDebugctl();
}
/**
* @brief Get the guest state of IA32_DEBUGCTL on the target core from VMCS
* using VMCALL
*
* @return UINT64
*/
UINT64
VmFuncGetDebugctlVmcallOnTargetCore()
{
return CrossVmcallGetDebugctlVmcallOnTargetCore();
}
/**
* @brief Get the guest state of IA32_LBR_CTL
*
* @return UINT64
*/
UINT64
VmFuncGetGuestIa32LbrCtl()
{
return HvGetGuestIa32LbrCtl();
}
/**
* @brief Get the guest state of IA32_LBR_CTL on the target core from VMCS
*
* @return UINT64
*/
UINT64
VmFuncGetGuestIa32LbrCtlVmcallOnTargetCore()
{
return CrossVmcallGetGuestIa32LbrCtlVmcallOnTargetCore();
}
/**
* @brief Check if CPU support save and load debug controls on exit and load entries
*
* @return BOOLEAN
*/
BOOLEAN
VmFuncCheckCpuSupportForSaveAndLoadDebugControls()
{
return HvCheckCpuSupportForSaveAndLoadDebugControls();
}
/**
* @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on VM-entry and VM-exit
*
* @return BOOLEAN
*/
BOOLEAN
VmFuncCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
{
return HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls();
}
/**
* @brief Set the guest state of IA32_DEBUGCTL
* @param Value
*
* @return VOID
*/
VOID
VmFuncSetDebugctl(UINT64 Value)
{
HvSetDebugctl(Value);
}
/**
* @brief Set the guest state of IA32_DEBUGCTL on the target core from VMCS
* using VMCALL
* @param Value
*
* @return VOID
*/
VOID
VmFuncSetDebugctlVmcallOnTargetCore(UINT64 Value)
{
CrossVmcallSetDebugctlVmcallOnTargetCore(Value);
}
/**
* @brief Set the guest state of IA32_LBR_CTL
* @param Value
*
* @return VOID
*/
VOID
VmFuncSetGuestIa32LbrCtl(UINT64 Value)
{
HvSetGuestIa32LbrCtl(Value);
}
/**
* @brief Set the guest state of IA32_LBR_CTL on the target core from VMCS
* using VMCALL
* @param Value
*
* @return VOID
*/
VOID
VmFuncSetGuestIa32LbrCtlVmcallOnTargetCore(UINT64 Value)
{
CrossVmcallSetGuestIa32LbrCtlVmcallOnTargetCore(Value);
}
/**
* @brief Set the guest state of MSR_LEGACY_LBR_SELECT
* @param FilterOptions
*
* @return VOID
*/
VOID
VmFuncSetLbrSelect(UINT64 FilterOptions)
{
HvSetLbrSelect(FilterOptions);
}
/**
* @brief Set the guest state of MSR_LEGACY_LBR_SELECT on the target core from VMCS using VMCALL
* @param FilterOptions
*
* @return VOID
*/
VOID
VmFuncSetLbrSelectVmcallOnTargetCore(UINT64 FilterOptions)
{
CrossVmcallSetLbrSelectVmcallOnTargetCore(FilterOptions);
}
/**
* @brief Set LOAD DEBUG CONTROLS on VM-entry controls on the target core from VMCS using VMCALL
*
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetLoadDebugControlsVmcallOnTargetCore(BOOLEAN Set)
{
CrossVmcallSetLoadDebugControlsVmcallOnTargetCore(Set);
}
/**
* @brief Set LOAD GUEST IA32_LBR_CTL on VM-entry controls on the target core from VMCS using VMCALL
*
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetLoadGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
{
CrossVmcallSetLoadGuestIa32LbrCtlVmcallOnTargetCore(Set);
}
/**
* @brief Set SAVE DEBUG CONTROLS on VM-exit controls on the target core from VMCS using VMCALL
*
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetSaveDebugControlsVmcallOnTargetCore(BOOLEAN Set)
{
CrossVmcallSetSaveDebugControlsVmcallOnTargetCore(Set);
}
/**
* @brief Set CLEAR GUEST IA32_LBR_CTL on VM-exit controls on the target core from VMCS using VMCALL
*
* @param Set Set or unset
*
* @return VOID
*/
VOID
VmFuncSetClearGuestIa32LbrCtlVmcallOnTargetCore(BOOLEAN Set)
{
CrossVmcallSetClearGuestIa32LbrCtlVmcallOnTargetCore(Set);
}
/**
* @brief Set the guest state of DR7
* @param Value
*
* @return VOID
*/
VOID
VmFuncSetDebugReg7(UINT64 Value)
{
HvSetDebugReg7(Value);
}
/**
* @brief Read guest's interruptibility state
*
@ -589,6 +839,18 @@ VmFuncSetTriggerEventForCpuids(BOOLEAN Set)
g_TriggerEventForCpuids = Set;
}
/**
* @brief Set trigger event for XSETBVs
*
* @param Set Set or unset the trigger
* @return VOID
*/
VOID
VmFuncSetTriggerEventForXsetbvs(BOOLEAN Set)
{
g_TriggerEventForXsetbvs = Set;
}
/**
* @brief VMX-root compatible strlen
* @param s A pointer to the string
@ -608,7 +870,7 @@ VmFuncVmxCompatibleStrlen(const CHAR * s)
* @return UINT32
*/
UINT32
VmFuncVmxCompatibleWcslen(const wchar_t * s)
VmFuncVmxCompatibleWcslen(const WCHAR * s)
{
return VmxCompatibleWcslen(s);
}
@ -692,10 +954,10 @@ VmFuncEventInjectInterruption(UINT32 InterruptionType,
* @return NTSTATUS
*/
NTSTATUS
VmFuncVmxVmcall(unsigned long long VmcallNumber,
unsigned long long OptionalParam1,
unsigned long long OptionalParam2,
unsigned long long OptionalParam3)
VmFuncVmxVmcall(UINT64 VmcallNumber,
UINT64 OptionalParam1,
UINT64 OptionalParam2,
UINT64 OptionalParam3)
{
return AsmVmxVmcall(VmcallNumber, OptionalParam1, OptionalParam2, OptionalParam3);
}
@ -768,7 +1030,7 @@ VmFuncVmxCompatibleStrncmp(const CHAR * Address1, const CHAR * Address2, SIZE_T
* @return INT32
*/
INT32
VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
VmFuncVmxCompatibleWcscmp(const WCHAR * Address1, const WCHAR * Address2)
{
return VmxCompatibleWcscmp(Address1, Address2, NULL_ZERO, FALSE);
}
@ -782,7 +1044,7 @@ VmFuncVmxCompatibleWcscmp(const wchar_t * Address1, const wchar_t * Address2)
* @return INT32
*/
INT32
VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, SIZE_T Num)
VmFuncVmxCompatibleWcsncmp(const WCHAR * Address1, const WCHAR * Address2, SIZE_T Num)
{
return VmxCompatibleWcscmp(Address1, Address2, Num, TRUE);
}
@ -796,14 +1058,14 @@ VmFuncVmxCompatibleWcsncmp(const wchar_t * Address1, const wchar_t * Address2, S
* @return INT32
*/
INT32
VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, size_t Count)
VmFuncVmxCompatibleMemcmp(const CHAR * Address1, const CHAR * Address2, SIZE_T Count)
{
return VmxCompatibleMemcmp(Address1, Address2, Count);
}
/**
* @brief Enables MTF and adjust external interrupt state
* @param UINT32 CoreId
* @param CoreId
*
* @return VOID
*/
@ -816,7 +1078,7 @@ VmFuncEnableMtfAndChangeExternalInterruptState(UINT32 CoreId)
/**
* @brief Checks to enable and reinject previous interrupts
*
* @param UINT32 CoreId
* @param CoreId
*
* @return VOID
*/
@ -865,3 +1127,18 @@ VmFuncIdtQueryEntries(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS IdtQueryReques
{
IdtEmulationQueryIdtEntriesRequest(IdtQueryRequest, ReadFromVmxRoot);
}
/**
* @brief Perform actions related to System Management Interrupts (SMIs)
*
* @param SmiOperationRequest
* @param ApplyFromVmxRootMode
*
* @return BOOLEAN
*/
BOOLEAN
VmFuncSmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest,
BOOLEAN ApplyFromVmxRootMode)
{
return SmmPerformSmiOperation(SmiOperationRequest, ApplyFromVmxRootMode);
}

View file

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

View file

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

View file

@ -76,7 +76,7 @@ LayoutGetExactGuestProcessCr3()
{
CR3_TYPE GuestCr3 = {0};
__vmx_vmread(VMCS_GUEST_CR3, &GuestCr3.Flags);
VmxVmread64P(VMCS_GUEST_CR3, &GuestCr3.Flags);
return GuestCr3;
}

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,140 @@
/**
* @file Smm.c
* @author Sina Karvandi (sina@hyperdbg.org)
* @brief Routines for operations related to System Management Mode (SMM)
* @details
*
* @version 0.15
* @date 2025-08-02
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
/*
* @brief Read the count of System Management Interrupts (SMIs)
*
* @return UINT64
*/
UINT64
SmmReadSmiCount()
{
UINT64 SmiCount = 0;
//
// Read the SMI count from MSR
//
SmiCount = (UINT64)CpuReadMsr(MSR_SMI_COUNT);
return SmiCount;
}
/*
* @brief Trigger a Power SMI
*
* @return BOOLEAN
*/
BOOLEAN
SmmTriggerPowerSmi()
{
UINT8 SmmResponse = 0;
//
// check the initial value received from 0xB3 port
//
SmmResponse = CpuIoInByte(0xb2);
//
// write to 0xB2 port to cause SMI
//
CpuIoOutByte(0xb2, SMI_TRIGGER_POWER_VALUE);
//
// Check the response in port 0xB3
//
SmmResponse = CpuIoInByte(0xb2);
if (SmmResponse == SMI_TRIGGER_POWER_VALUE)
{
//
// If the response is SMI_TRIGGER_POWER_VALUE, it means the SMI was triggered successfully
//
return TRUE;
}
else
{
//
// If the response is not SMI_TRIGGER_POWER_VALUE, it means the SMI was not triggered successfully
//
return FALSE;
}
}
/**
* @brief Perform actions related to System Management Interrupts (SMIs)
*
* @param SmiOperationRequest
* @param ApplyFromVmxRootMode
*
* @return BOOLEAN
*/
BOOLEAN
SmmPerformSmiOperation(SMI_OPERATION_PACKETS * SmiOperationRequest, BOOLEAN ApplyFromVmxRootMode)
{
BOOLEAN Status = FALSE;
UNREFERENCED_PARAMETER(ApplyFromVmxRootMode);
//
// Check the SMI operation type and perform the corresponding action
//
switch (SmiOperationRequest->SmiOperationType)
{
case SMI_OPERATION_REQUEST_TYPE_READ_COUNT:
//
// Read the SMI count from the MSR
//
SmiOperationRequest->SmiCount = SmmReadSmiCount();
Status = TRUE;
break;
case SMI_OPERATION_REQUEST_TYPE_TRIGGER_POWER_SMI:
if (SmmTriggerPowerSmi())
{
//
// If the SMI was triggered successfully
//
Status = TRUE;
}
else
{
//
// If the SMI was not triggered successfully, set error status
//
SmiOperationRequest->KernelStatus = DEBUGGER_ERROR_UNABLE_TO_TRIGGER_SMI;
}
break;
default:
Status = FALSE;
SmiOperationRequest->KernelStatus = DEBUGGER_ERROR_INVALID_SMI_OPERATION_PARAMETERS;
break;
}
//
// Set the status of the SMI operation request
//
if (Status)
{
SmiOperationRequest->KernelStatus = DEBUGGER_OPERATION_WAS_SUCCESSFUL;
}
return Status;
}

View file

@ -23,9 +23,9 @@ EptCheckFeatures(VOID)
{
IA32_VMX_EPT_VPID_CAP_REGISTER VpidRegister;
IA32_MTRR_DEF_TYPE_REGISTER MTRRDefType;
VpidRegister.AsUInt = __readmsr(IA32_VMX_EPT_VPID_CAP);
MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
g_IsVpidSupported = FALSE;
VpidRegister.AsUInt = CpuReadMsr(IA32_VMX_EPT_VPID_CAP);
MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
if (!VpidRegister.PageWalkLength4 || !VpidRegister.MemoryTypeWriteBack || !VpidRegister.Pde2MbPages)
{
@ -37,6 +37,17 @@ EptCheckFeatures(VOID)
LogDebugInfo("The processor doesn't report advanced VM-exit information for EPT violations");
}
if (VpidRegister.Invvpid &&
VpidRegister.InvvpidAllContexts &&
VpidRegister.InvvpidIndividualAddress &&
VpidRegister.InvvpidSingleContext &&
VpidRegister.InvvpidSingleContextRetainGlobals &&
!g_IsTopLevelHypervisorHyperV)
{
g_IsVpidSupported = TRUE;
LogDebugInfo("The processor supports VPID");
}
if (!VpidRegister.ExecuteOnlyPages)
{
g_CompatibilityCheck.ExecuteOnlySupport = FALSE;
@ -163,8 +174,8 @@ EptBuildMtrrMap(VOID)
UINT32 CurrentRegister;
UINT32 NumberOfBitsInMask;
MTRRCap.AsUInt = __readmsr(IA32_MTRR_CAPABILITIES);
MTRRDefType.AsUInt = __readmsr(IA32_MTRR_DEF_TYPE);
MTRRCap.AsUInt = CpuReadMsr(IA32_MTRR_CAPABILITIES);
MTRRDefType.AsUInt = CpuReadMsr(IA32_MTRR_DEF_TYPE);
//
// All MTRRs are disabled when clear, and the
@ -200,8 +211,8 @@ EptBuildMtrrMap(VOID)
{
const UINT32 K64Base = 0x0;
const UINT32 K64Size = 0x10000;
IA32_MTRR_FIXED_RANGE_TYPE K64Types = {__readmsr(IA32_MTRR_FIX64K_00000)};
for (unsigned int i = 0; i < 8; i++)
IA32_MTRR_FIXED_RANGE_TYPE K64Types = {CpuReadMsr(IA32_MTRR_FIX64K_00000)};
for (UINT32 i = 0; i < 8; i++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K64Types.s.Types[i];
@ -212,10 +223,10 @@ EptBuildMtrrMap(VOID)
const UINT32 K16Base = 0x80000;
const UINT32 K16Size = 0x4000;
for (unsigned int i = 0; i < 2; i++)
for (UINT32 i = 0; i < 2; i++)
{
IA32_MTRR_FIXED_RANGE_TYPE K16Types = {__readmsr(IA32_MTRR_FIX16K_80000 + i)};
for (unsigned int j = 0; j < 8; j++)
IA32_MTRR_FIXED_RANGE_TYPE K16Types = {CpuReadMsr(IA32_MTRR_FIX16K_80000 + i)};
for (UINT32 j = 0; j < 8; j++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K16Types.s.Types[j];
@ -227,11 +238,11 @@ EptBuildMtrrMap(VOID)
const UINT32 K4Base = 0xC0000;
const UINT32 K4Size = 0x1000;
for (unsigned int i = 0; i < 8; i++)
for (UINT32 i = 0; i < 8; i++)
{
IA32_MTRR_FIXED_RANGE_TYPE K4Types = {__readmsr(IA32_MTRR_FIX4K_C0000 + i)};
IA32_MTRR_FIXED_RANGE_TYPE K4Types = {CpuReadMsr(IA32_MTRR_FIX4K_C0000 + i)};
for (unsigned int j = 0; j < 8; j++)
for (UINT32 j = 0; j < 8; j++)
{
Descriptor = &g_EptState->MemoryRanges[g_EptState->NumberOfEnabledMemoryRanges++];
Descriptor->MemoryType = K4Types.s.Types[j];
@ -247,8 +258,8 @@ EptBuildMtrrMap(VOID)
//
// For each dynamic register pair
//
CurrentPhysBase.AsUInt = __readmsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
CurrentPhysMask.AsUInt = __readmsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
CurrentPhysBase.AsUInt = CpuReadMsr(IA32_MTRR_PHYSBASE0 + (CurrentRegister * 2));
CurrentPhysMask.AsUInt = CpuReadMsr(IA32_MTRR_PHYSMASK0 + (CurrentRegister * 2));
//
// Is the range enabled?
@ -270,7 +281,7 @@ EptBuildMtrrMap(VOID)
// Calculate the total size of the range
// The lowest bit of the mask that is set to 1 specifies the size of the range
//
_BitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
CpuBitScanForward64((ULONG *)&NumberOfBitsInMask, CurrentPhysMask.PageFrameNumber * PAGE_SIZE);
//
// Size of the range in bytes + Base Address
@ -293,6 +304,28 @@ EptBuildMtrrMap(VOID)
return TRUE;
}
/**
* @brief Resolve the split PML1 VA that belongs to a given PML2 entry
*
* @param EptPageTable The EPT page table
* @param TargetEntry The target PML2 entry
* @return PEPT_PML1_ENTRY Returns base VA of PML1 page, or NULL if not tracked
*/
_Must_inspect_result_
static PEPT_PML1_ENTRY
EptGetSplitPml1VaByPml2Entry(_In_ PVMM_EPT_PAGE_TABLE EptPageTable, _In_ PEPT_PML2_ENTRY TargetEntry)
{
LIST_FOR_EACH_LINK(EptPageTable->DynamicSplitList, VMM_EPT_DYNAMIC_SPLIT, DynamicSplitList, CurrentSplit)
{
if (CurrentSplit->Fields.Entry == TargetEntry)
{
return &CurrentSplit->PML1[0];
}
}
return NULL;
}
/**
* @brief Get the PML1 entry for this physical address if the page is split
*
@ -303,10 +336,9 @@ EptBuildMtrrMap(VOID)
PEPT_PML1_ENTRY
EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
{
SIZE_T Directory, DirectoryPointer, PML4Entry;
PEPT_PML2_ENTRY PML2;
PEPT_PML1_ENTRY PML1;
PEPT_PML2_POINTER PML2Pointer;
SIZE_T Directory, DirectoryPointer, PML4Entry;
PEPT_PML2_ENTRY PML2;
PEPT_PML1_ENTRY PML1;
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
@ -331,15 +363,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
}
//
// Conversion to get the right PageFrameNumber.
// These pointers occupy the same place in the table and are directly convertible.
// Resolve the split PML1 VA that was recorded during EptSplitLargePage
//
PML2Pointer = (PEPT_PML2_POINTER)PML2;
//
// If it is, translate to the PML1 pointer
//
PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
if (!PML1)
{
@ -367,10 +393,9 @@ EptGetPml1Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
PVOID
EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress, BOOLEAN * IsLargePage)
{
SIZE_T Directory, DirectoryPointer, PML4Entry;
PEPT_PML2_ENTRY PML2;
PEPT_PML1_ENTRY PML1;
PEPT_PML2_POINTER PML2Pointer;
SIZE_T Directory, DirectoryPointer, PML4Entry;
PEPT_PML2_ENTRY PML2;
PEPT_PML1_ENTRY PML1;
Directory = ADDRMASK_EPT_PML2_INDEX(PhysicalAddress);
DirectoryPointer = ADDRMASK_EPT_PML3_INDEX(PhysicalAddress);
@ -396,15 +421,9 @@ EptGetPml1OrPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress,
}
//
// Conversion to get the right PageFrameNumber.
// These pointers occupy the same place in the table and are directly convertible.
// Resolve the split PML1 VA that was recorded during EptSplitLargePage
//
PML2Pointer = (PEPT_PML2_POINTER)PML2;
//
// If it is, translate to the PML1 pointer
//
PML1 = (PEPT_PML1_ENTRY)PhysicalAddressToVirtualAddress(PML2Pointer->PageFrameNumber * PAGE_SIZE);
PML1 = EptGetSplitPml1VaByPml2Entry(EptPageTable, PML2);
if (!PML1)
{
@ -450,17 +469,17 @@ EptGetPml2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, SIZE_T PhysicalAddress)
}
/**
* @brief Split 2MB (LargePage) into 4kb pages
* @brief Convert large pages to 4KB pages
*
* @param EptPageTable The EPT Page Table
* @param PreAllocatedBuffer The address of pre-allocated buffer
* @param UsePreAllocatedBuffer Whether allocate a memory or use pre-allocated buffer
* @param PhysicalAddress Physical address of where we want to split
*
* @return BOOLEAN Returns true if it was successful or false if there was an error
*/
BOOLEAN
EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
PVOID PreAllocatedBuffer,
BOOLEAN UsePreAllocatedBuffer,
SIZE_T PhysicalAddress)
{
PVMM_EPT_DYNAMIC_SPLIT NewSplit;
@ -486,19 +505,21 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
if (!TargetEntry->LargePage)
{
//
// As it's a large page and we request a pool for it, we need to
// free the pool because it's not used anymore
//
PoolManagerFreePool((UINT64)PreAllocatedBuffer);
return TRUE;
}
//
// Allocate the PML1 entries
//
NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PreAllocatedBuffer;
if (UsePreAllocatedBuffer)
{
NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PoolManagerCallbackRequestPool(SPLIT_2MB_PAGING_TO_4KB_PAGE, TRUE, sizeof(VMM_EPT_DYNAMIC_SPLIT));
}
else
{
NewSplit = (PVMM_EPT_DYNAMIC_SPLIT)PlatformMemAllocateNonPagedPool(sizeof(VMM_EPT_DYNAMIC_SPLIT));
}
if (!NewSplit)
{
LogError("Err, failed to allocate dynamic split memory");
@ -510,7 +531,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
// Point back to the entry in the dynamic split for easy reference for which entry that
// dynamic split is for
//
NewSplit->u.Entry = TargetEntry;
NewSplit->Fields.Entry = TargetEntry;
//
// Make a template for RWX
@ -542,7 +563,7 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
// Copy the template into all the PML1 entries
//
__stosq((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
CpuStosQ((SIZE_T *)&NewSplit->PML1[0], EntryTemplate.AsUInt, VMM_EPT_PML1E_COUNT);
//
// Set the page frame numbers for identity mapping
@ -583,6 +604,12 @@ EptSplitLargePage(PVMM_EPT_PAGE_TABLE EptPageTable,
//
RtlCopyMemory(TargetEntry, &NewPointer, sizeof(NewPointer));
//
// Track the split so we can directly resolve PML1 VA from PML2 entry
// without any PA->VA reverse translation
//
InsertHeadList(&EptPageTable->DynamicSplitList, &(NewSplit->DynamicSplitList));
return TRUE;
}
@ -627,8 +654,6 @@ EptIsValidForLargePage(SIZE_T PageFrameNumber)
BOOLEAN
EptSetupPML2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, PEPT_PML2_ENTRY NewEntry, SIZE_T PageFrameNumber)
{
PVOID TargetBuffer;
//
// Each of the 512 collections of 512 PML2 entries is setup here
// This will, in total, identity map every physical address from 0x0
@ -646,15 +671,10 @@ EptSetupPML2Entry(PVMM_EPT_PAGE_TABLE EptPageTable, PEPT_PML2_ENTRY NewEntry, SI
}
else
{
TargetBuffer = (PVOID)PlatformMemAllocateNonPagedPool(sizeof(VMM_EPT_DYNAMIC_SPLIT));
if (!TargetBuffer)
{
LogError("Err, cannot allocate page for splitting edge large pages");
return FALSE;
}
return EptSplitLargePage(EptPageTable, TargetBuffer, PageFrameNumber * SIZE_2_MB);
//
// Here we won't need to use pre-allocated buffers
//
return EptSplitLargePage(EptPageTable, FALSE, PageFrameNumber * SIZE_2_MB);
}
}
@ -689,6 +709,11 @@ EptAllocateAndCreateIdentityPageTable(VOID)
return NULL;
}
//
// Keep track of dynamic 2MB->4KB split metadata for this EPT table.
//
InitializeListHead(&PageTable->DynamicSplitList);
//
// Create the template for the first entry in the PML4
//
@ -699,7 +724,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// Copy the template into each of the 512 PML4 entry slots
//
__stosq((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
CpuStosQ((SIZE_T *)&PageTable->PML4[1], PageTable->PML4[0].AsUInt, VMM_EPT_PML4E_COUNT - 1);
for (int i = 0; i < VMM_EPT_PML4E_COUNT; i++)
{
@ -744,14 +769,14 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// Copy the template into each of the 512 PML3 entry slots for the original entries
//
__stosq((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
CpuStosQ((SIZE_T *)&PageTable->PML3[0], PML3Template.AsUInt, VMM_EPT_PML3E_COUNT);
//
// Copt the template into each of the 512 PML3 entry slots for the reserved entries
//
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
{
__stosq((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
CpuStosQ((SIZE_T *)&PageTable->PML3_RSVD[i][0], PML3TemplateLarge.AsUInt, VMM_EPT_PML3E_COUNT);
}
//
@ -769,9 +794,9 @@ EptAllocateAndCreateIdentityPageTable(VOID)
//
// For each of the 512 PML3 reserved entries for reserved PML3 entries
//
for (size_t i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
for (SIZE_T i = 0; i < VMM_EPT_PML4E_COUNT - 1; i++)
{
for (size_t j = 0; j < VMM_EPT_PML3E_COUNT; j++)
for (SIZE_T j = 0; j < VMM_EPT_PML3E_COUNT; j++)
{
//
// Map the 1GB PML3 reserved entry to 512 PML3 (1GB) entries to describe each large page
@ -808,7 +833,7 @@ EptAllocateAndCreateIdentityPageTable(VOID)
// this region or not. We will cause a fault in our EPT handler if the guest access a page
// outside a usable range, despite the EPT frame being present here
//
__stosq((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
CpuStosQ((SIZE_T *)&PageTable->PML2[0], PML2EntryTemplate.AsUInt, VMM_EPT_PML3E_COUNT * VMM_EPT_PML2E_COUNT);
//
// For each of the 512 collections of 512 2MB PML2 entries
@ -848,7 +873,7 @@ EptLogicalProcessorInitialize(VOID)
//
ProcessorsCount = KeQueryActiveProcessorCount(0);
for (size_t i = 0; i < ProcessorsCount; i++)
for (SIZE_T i = 0; i < ProcessorsCount; i++)
{
//
// Allocate the identity mapped page table
@ -860,7 +885,7 @@ EptLogicalProcessorInitialize(VOID)
//
// Try to deallocate previous pools (if any)
//
for (size_t j = 0; j < ProcessorsCount; j++)
for (SIZE_T j = 0; j < ProcessorsCount; j++)
{
if (g_GuestState[j].EptPageTable != NULL)
{
@ -1088,19 +1113,19 @@ EptHandleEptViolation(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest physical address
//
__vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
if (ExecTrapHandleEptViolationVmexit(VCpu, &ViolationQualification))
{
return TRUE;
}
else if (EptHandlePageHookExit(VCpu, ViolationQualification, GuestPhysicalAddr))
if (EptHandlePageHookExit(VCpu, ViolationQualification, GuestPhysicalAddr))
{
//
// Handled by page hook code
//
return TRUE;
}
else if (ExecTrapHandleEptViolationVmexit(VCpu, &ViolationQualification))
{
return TRUE;
}
else if (VmmCallbackUnhandledEptViolation(VCpu->CoreId, (UINT64)ViolationQualification.AsUInt, GuestPhysicalAddr))
{
//
@ -1128,7 +1153,7 @@ EptHandleMisconfiguration(VOID)
{
UINT64 GuestPhysicalAddr = 0;
__vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
VmxVmread64P(VMCS_GUEST_PHYSICAL_ADDRESS, &GuestPhysicalAddr);
LogInfo("EPT Misconfiguration!");
@ -1211,7 +1236,7 @@ EptCheckAndHandleEptHookBreakpoints(VIRTUAL_MACHINE_STATE * VCpu, UINT64 GuestRi
if (HookedEntry->IsExecutionHook)
{
for (size_t i = 0; i < HookedEntry->CountOfBreakpoints; i++)
for (SIZE_T i = 0; i < HookedEntry->CountOfBreakpoints; i++)
{
if (HookedEntry->BreakpointAddresses[i] == GuestRip)
{
@ -1297,7 +1322,7 @@ EptCheckAndHandleBreakpoint(VIRTUAL_MACHINE_STATE * VCpu)
//
// Reading guest's RIP
//
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
//
// Don't increment rip by default

View file

@ -25,6 +25,12 @@ VpidInvvpid(INVVPID_TYPE Type, INVVPID_DESCRIPTOR * Descriptor)
INVVPID_DESCRIPTOR * TargetDescriptor = NULL;
INVVPID_DESCRIPTOR ZeroDescriptor = {0};
// No need to do anything if VPID is not supported.
if (!g_IsVpidSupported)
{
return;
}
if (!Descriptor)
{
TargetDescriptor = &ZeroDescriptor;

View file

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

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

View file

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

View file

@ -24,7 +24,7 @@ HvAdjustControls(UINT32 Ctl, UINT32 Msr)
{
MSR MsrValue = {0};
MsrValue.Flags = __readmsr(Msr);
MsrValue.Flags = CpuReadMsr(Msr);
Ctl &= MsrValue.Fields.High; /* bit == 0 in high word ==> must be zero */
Ctl |= MsrValue.Fields.Low; /* bit == 1 in low word ==> must be one */
return Ctl;
@ -73,7 +73,7 @@ HvHandleCpuid(VIRTUAL_MACHINE_STATE * VCpu)
// Otherwise, issue the CPUID to the logical processor based on the indexes
// on the VP's GPRs.
//
__cpuidex(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
CpuCpuIdEx(CpuInfo, (INT32)Regs->rax, (INT32)Regs->rcx);
//
// check whether we are in transparent mode or not
@ -158,7 +158,7 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
/*
if (CrExitQualification->Fields.Register == 4)
{
__vmx_vmread(VMCS_GUEST_RSP, &GuestRsp);
VmxVmread64P(VMCS_GUEST_RSP, &GuestRsp);
*RegPtr = GuestRsp;
}
*/
@ -229,19 +229,19 @@ HvHandleControlRegisterAccess(VIRTUAL_MACHINE_STATE * VCpu,
{
case VMX_EXIT_QUALIFICATION_REGISTER_CR0:
__vmx_vmread(VMCS_GUEST_CR0, RegPtr);
VmxVmread64P(VMCS_GUEST_CR0, RegPtr);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_CR3:
__vmx_vmread(VMCS_GUEST_CR3, RegPtr);
VmxVmread64P(VMCS_GUEST_CR3, RegPtr);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_CR4:
__vmx_vmread(VMCS_GUEST_CR4, RegPtr);
VmxVmread64P(VMCS_GUEST_CR4, RegPtr);
break;
@ -299,10 +299,10 @@ HvResumeToNextInstruction()
{
UINT64 ResumeRIP = NULL64_ZERO;
UINT64 CurrentRIP = NULL64_ZERO;
size_t ExitInstructionLength = 0;
SIZE_T ExitInstructionLength = 0;
__vmx_vmread(VMCS_GUEST_RIP, &CurrentRIP);
__vmx_vmread(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
VmxVmread64P(VMCS_GUEST_RIP, &CurrentRIP);
VmxVmread64P(VMCS_VMEXIT_INSTRUCTION_LENGTH, &ExitInstructionLength);
ResumeRIP = CurrentRIP + ExitInstructionLength;
@ -353,11 +353,11 @@ HvSetMonitorTrapFlag(BOOLEAN Set)
if (Set)
{
CpuBasedVmExecControls |= CPU_BASED_MONITOR_TRAP_FLAG;
CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_MONITOR_TRAP_FLAG_FLAG;
}
else
{
CpuBasedVmExecControls &= ~CPU_BASED_MONITOR_TRAP_FLAG;
CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_MONITOR_TRAP_FLAG_FLAG;
}
//
@ -391,12 +391,28 @@ HvSetRflagTrapFlag(BOOLEAN Set)
/**
* @brief Set LOAD DEBUG CONTROLS on Vm-entry controls
*
* @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
HvSetLoadDebugControls(BOOLEAN Set)
HvSetLoadDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
ProtectedHvSetLoadDebugControls(VCpu, Set);
}
/**
* @brief Set LOAD GUEST IA32_LBR_CTL on Vm-entry controls
*
* @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
HvSetLoadGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
UNREFERENCED_PARAMETER(VCpu);
UINT32 VmentryControls = 0;
//
@ -406,28 +422,44 @@ HvSetLoadDebugControls(BOOLEAN Set)
if (Set)
{
VmentryControls |= VM_ENTRY_LOAD_DEBUG_CONTROLS;
VmentryControls |= IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
}
else
{
VmentryControls &= ~VM_ENTRY_LOAD_DEBUG_CONTROLS;
VmentryControls &= ~IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG;
}
//
// Set the new value
//
VmxVmwrite64(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
VmxVmwrite32(VMCS_CTRL_VMENTRY_CONTROLS, VmentryControls);
}
/**
* @brief Set SAVE DEBUG CONTROLS on Vm-exit controls
*
* @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
HvSetSaveDebugControls(BOOLEAN Set)
HvSetSaveDebugControls(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
ProtectedHvSetSaveDebugControls(VCpu, Set);
}
/**
* @brief Set SAVE GUEST IA32_LBR_CTL on Vm-exit controls
*
* @param VCpu
* @param Set Set or unset
* @return VOID
*/
VOID
HvSetClearGuestIa32LbrCtl(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
{
UNREFERENCED_PARAMETER(VCpu);
UINT32 VmexitControls = 0;
//
@ -437,17 +469,17 @@ HvSetSaveDebugControls(BOOLEAN Set)
if (Set)
{
VmexitControls |= VM_EXIT_SAVE_DEBUG_CONTROLS;
VmexitControls |= IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
}
else
{
VmexitControls &= ~VM_EXIT_SAVE_DEBUG_CONTROLS;
VmexitControls &= ~IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG;
}
//
// Set the new value
//
VmxVmwrite64(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
VmxVmwrite32(VMCS_CTRL_PRIMARY_VMEXIT_CONTROLS, VmexitControls);
}
/**
@ -472,22 +504,22 @@ HvRestoreRegisters()
//
// Restore FS Base
//
__vmx_vmread(VMCS_GUEST_FS_BASE, &FsBase);
__writemsr(IA32_FS_BASE, FsBase);
VmxVmread64P(VMCS_GUEST_FS_BASE, &FsBase);
CpuWriteMsr(IA32_FS_BASE, FsBase);
//
// Restore Gs Base
//
__vmx_vmread(VMCS_GUEST_GS_BASE, &GsBase);
__writemsr(IA32_GS_BASE, GsBase);
VmxVmread64P(VMCS_GUEST_GS_BASE, &GsBase);
CpuWriteMsr(IA32_GS_BASE, GsBase);
//
// Restore GDTR
//
__vmx_vmread(VMCS_GUEST_GDTR_BASE, &GdtrBase);
__vmx_vmread(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
VmxVmread64P(VMCS_GUEST_GDTR_BASE, &GdtrBase);
VmxVmread64P(VMCS_GUEST_GDTR_LIMIT, &GdtrLimit);
AsmReloadGdtr((void *)GdtrBase, (unsigned long)GdtrLimit);
AsmReloadGdtr((PVOID)GdtrBase, (ULONG)GdtrLimit);
//
// Restore Segment Selector
@ -504,10 +536,10 @@ HvRestoreRegisters()
//
// Restore IDTR
//
__vmx_vmread(VMCS_GUEST_IDTR_BASE, &IdtrBase);
__vmx_vmread(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
VmxVmread64P(VMCS_GUEST_IDTR_BASE, &IdtrBase);
VmxVmread64P(VMCS_GUEST_IDTR_LIMIT, &IdtrLimit);
AsmReloadIdtr((void *)IdtrBase, (unsigned long)IdtrLimit);
AsmReloadIdtr((PVOID)IdtrBase, (ULONG)IdtrLimit);
}
/**
@ -529,11 +561,11 @@ HvSetPmcVmexit(BOOLEAN Set)
if (Set)
{
CpuBasedVmExecControls |= CPU_BASED_RDPMC_EXITING;
CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_RDPMC_EXITING_FLAG;
}
else
{
CpuBasedVmExecControls &= ~CPU_BASED_RDPMC_EXITING;
CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_RDPMC_EXITING_FLAG;
}
//
@ -629,11 +661,11 @@ HvSetInterruptWindowExiting(BOOLEAN Set)
//
if (Set)
{
CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_INTR_PENDING;
CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_INTERRUPT_WINDOW_EXITING_FLAG;
}
else
{
CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_INTERRUPT_WINDOW_EXITING_FLAG;
}
//
@ -737,11 +769,11 @@ HvSetNmiWindowExiting(BOOLEAN Set)
//
if (Set)
{
CpuBasedVmExecControls |= CPU_BASED_VIRTUAL_NMI_PENDING;
CpuBasedVmExecControls |= IA32_VMX_PROCBASED_CTLS_NMI_WINDOW_EXITING_FLAG;
}
else
{
CpuBasedVmExecControls &= ~CPU_BASED_VIRTUAL_NMI_PENDING;
CpuBasedVmExecControls &= ~IA32_VMX_PROCBASED_CTLS_NMI_WINDOW_EXITING_FLAG;
}
//
@ -860,11 +892,11 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
if (Dr7.GeneralDetect)
{
DR6 Dr6 = {
.AsUInt = __readdr(6),
.AsUInt = CpuReadDr(6),
.BreakpointCondition = 0,
.DebugRegisterAccessDetected = TRUE};
__writedr(6, Dr6.AsUInt);
CpuWriteDr(6, Dr6.AsUInt);
Dr7.GeneralDetect = FALSE;
@ -906,22 +938,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
switch (ExitQualification.DebugRegister)
{
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6, GpRegister);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
__writedr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
CpuWriteDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7, GpRegister);
break;
default:
break;
@ -932,22 +964,22 @@ HvHandleMovDebugRegister(VIRTUAL_MACHINE_STATE * VCpu)
switch (ExitQualification.DebugRegister)
{
case VMX_EXIT_QUALIFICATION_REGISTER_DR0:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR0);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR1:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR1);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR2:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR2);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR3:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR3);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR6:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR6);
break;
case VMX_EXIT_QUALIFICATION_REGISTER_DR7:
GpRegister = __readdr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
GpRegister = CpuReadDr(VMX_EXIT_QUALIFICATION_REGISTER_DR7);
break;
default:
break;
@ -978,13 +1010,13 @@ HvSetNmiExiting(BOOLEAN Set)
if (Set)
{
PinBasedControls |= PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING;
VmExitControls |= VM_EXIT_ACK_INTR_ON_EXIT;
PinBasedControls |= IA32_VMX_PINBASED_CTLS_NMI_EXITING_FLAG;
VmExitControls |= IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
else
{
PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_NMI_EXITING;
VmExitControls &= ~VM_EXIT_ACK_INTR_ON_EXIT;
PinBasedControls &= ~IA32_VMX_PINBASED_CTLS_NMI_EXITING_FLAG;
VmExitControls &= ~IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG;
}
//
@ -1012,11 +1044,11 @@ HvSetVmxPreemptionTimerExiting(BOOLEAN Set)
if (Set)
{
PinBasedControls |= PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER;
PinBasedControls |= IA32_VMX_PINBASED_CTLS_ACTIVATE_VMX_PREEMPTION_TIMER_FLAG;
}
else
{
PinBasedControls &= ~PIN_BASED_VM_EXECUTION_CONTROLS_ACTIVE_VMX_TIMER;
PinBasedControls &= ~IA32_VMX_PINBASED_CTLS_ACTIVATE_VMX_PREEMPTION_TIMER_FLAG;
}
//
@ -1079,7 +1111,6 @@ HvSetExternalInterruptExiting(VIRTUAL_MACHINE_STATE * VCpu, BOOLEAN Set)
* @brief Checks to enable and reinject previous interrupts
*
* @param VCpu The virtual processor's state
* @param Set Set or unset the External Interrupt Exiting
*
* @return VOID
*/
@ -1152,7 +1183,7 @@ HvGetCsSelector()
//
UINT64 CsSel = NULL64_ZERO;
__vmx_vmread(VMCS_GUEST_CS_SELECTOR, &CsSel);
VmxVmread64P(VMCS_GUEST_CS_SELECTOR, &CsSel);
return CsSel & 0xffff;
}
@ -1167,7 +1198,7 @@ HvGetRflags()
{
UINT64 Rflags = NULL64_ZERO;
__vmx_vmread(VMCS_GUEST_RFLAGS, &Rflags);
VmxVmread64P(VMCS_GUEST_RFLAGS, &Rflags);
return Rflags;
}
@ -1194,7 +1225,7 @@ HvGetRip()
{
UINT64 Rip = NULL64_ZERO;
__vmx_vmread(VMCS_GUEST_RIP, &Rip);
VmxVmread64P(VMCS_GUEST_RIP, &Rip);
return Rip;
}
@ -1221,7 +1252,7 @@ HvGetInterruptibilityState()
{
UINT64 InterruptibilityState = NULL64_ZERO;
__vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
VmxVmread64P(VMCS_GUEST_INTERRUPTIBILITY_STATE, &InterruptibilityState);
return InterruptibilityState;
}
@ -1503,6 +1534,69 @@ HvGetDebugctl()
return (UINT64)HighPart << 32 | LowPart;
}
/**
* @brief Get the guest state of IA32_LBR_CTL
*
* @return UINT64
*/
UINT64
HvGetGuestIa32LbrCtl()
{
UINT64 GuestIa32LbrCtl;
VmxVmread64P(VMCS_GUEST_LBR_CTL, &GuestIa32LbrCtl);
return GuestIa32LbrCtl;
}
/**
* @brief Get and store the guest state of IA32_DEBUGCTL
* @details mainly used from the VMCALL handler
*
* @param StoreDebugctl
*
* @return VOID
*/
VOID
HvGetAndStoreDebugctl(UINT64 * StoreDebugctl)
{
UINT64 DebugctlValue;
//
// Read DEBUGCTL from VMCS
//
DebugctlValue = HvGetDebugctl();
//
// Store the DEBUGCTL
//
*StoreDebugctl = DebugctlValue;
}
/**
* @brief Get and store the guest state of IA32_LBR_CTL
* @details mainly used from the VMCALL handler
*
* @param StoreGuestIa32Lbr
*
* @return VOID
*/
VOID
HvGetAndStoreGuestIa32LbrCtl(UINT64 * StoreGuestIa32Lbr)
{
UINT64 GuestIa32LbrCtl;
//
// Read IA32_LBR_CTL from VMCS
//
GuestIa32LbrCtl = HvGetGuestIa32LbrCtl();
//
// Store the IA32_LBR_CTL
//
*StoreGuestIa32Lbr = GuestIa32LbrCtl;
}
/**
* @brief Set the guest state of IA32_DEBUGCTL
* @param Value The new state
@ -1512,8 +1606,141 @@ HvGetDebugctl()
VOID
HvSetDebugctl(UINT64 Value)
{
VmxVmwrite64(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
VmxVmwrite64(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
VmxVmwrite32(VMCS_GUEST_DEBUGCTL, Value & 0xFFFFFFFF);
VmxVmwrite32(VMCS_GUEST_DEBUGCTL_HIGH, Value >> 32);
}
/**
* @brief Set the guest state of IA32_LBR_CTL
* @param Value The new state
*
* @return VOID
*/
VOID
HvSetGuestIa32LbrCtl(UINT64 Value)
{
VmxVmwrite64(VMCS_GUEST_LBR_CTL, Value);
}
/**
* @brief Set LBR selector
* @details If VMM is active, this should be done in vmx-root, otherwise, it doesn't work
* @param FilterOptions The value to write on MSR_LEGACY_LBR_SELECT
*
* @return VOID
*/
VOID
HvSetLbrSelect(UINT64 FilterOptions)
{
CpuWriteMsr(MSR_LEGACY_LBR_SELECT, FilterOptions);
}
/**
* @brief Check if CPU support save and load debug controls on exit and load entries
*
* @return BOOLEAN
*/
BOOLEAN
HvCheckCpuSupportForSaveAndLoadDebugControls()
{
IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
//
// Reading IA32_VMX_BASIC_MSR
//
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
//
// Read 1-settings of save debug controls (exit controls)
//
UINT32 ExitCtls = HvAdjustControls(
IA32_VMX_EXIT_CTLS_SAVE_DEBUG_CONTROLS_FLAG,
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
//
// Read 1-settings of load debug controls (entry controls)
//
UINT32 EntryCtls = HvAdjustControls(
IA32_VMX_ENTRY_CTLS_LOAD_DEBUG_CONTROLS_FLAG,
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
//
// Check if entry and exit controls are supported on this system
//
if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
{
//
// Supported
//
return TRUE;
}
else
{
//
// Not supported
//
return FALSE;
}
}
/**
* @brief Check if CPU support load and clear guest IA32_LBR_CTL controls on entry and exit
*
* @return BOOLEAN
*/
BOOLEAN
HvCheckCpuSupportForLoadAndClearGuestIa32LbrCtlControls()
{
IA32_VMX_BASIC_REGISTER VmxBasicMsr = {0};
//
// Reading IA32_VMX_BASIC_MSR
//
VmxBasicMsr.AsUInt = CpuReadMsr(IA32_VMX_BASIC);
//
// Read 1-settings of save debug controls (exit controls)
//
UINT32 ExitCtls = HvAdjustControls(
IA32_VMX_EXIT_CTLS_CLEAR_IA32_LBR_CTL_FLAG,
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_EXIT_CTLS : IA32_VMX_EXIT_CTLS);
//
// Read 1-settings of load debug controls (entry controls)
//
UINT32 EntryCtls = HvAdjustControls(
IA32_VMX_ENTRY_CTLS_LOAD_IA32_LBR_CTL_FLAG,
VmxBasicMsr.VmxControls ? IA32_VMX_TRUE_ENTRY_CTLS : IA32_VMX_ENTRY_CTLS);
//
// Check if entry and exit controls are supported on this system
//
if (ExitCtls != NULL_ZERO && EntryCtls != NULL_ZERO)
{
//
// Supported
//
return TRUE;
}
else
{
//
// Not supported
//
return FALSE;
}
}
/**
* @brief Set the guest state of DR7
* @param Value The new value for DR7
*
* @return VOID
*/
VOID
HvSetDebugReg7(UINT64 Value)
{
VmxVmwrite64(VMCS_GUEST_DR7, Value);
}
/**

View file

@ -35,7 +35,7 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
//
// Since it's not in VMX Root, we can directly read the IDTR register
//
__sidt(&IdtrReg);
CpuSidt(&IdtrReg);
//
// Get the IDT base address
@ -55,9 +55,9 @@ IdtEmulationQueryIdtEntriesRequest(PINTERRUPT_DESCRIPTOR_TABLE_ENTRIES_PACKETS I
//
for (UINT32 i = 0; i < MAX_NUMBER_OF_IDT_ENTRIES; i++)
{
IdtQueryRequest->IdtEntry[i] = (UINT64)((unsigned long long)IdtEntries[i].HighestPart << 32) |
((unsigned long long)IdtEntries[i].HighPart << 16) |
(unsigned long long)IdtEntries[i].LowPart;
IdtQueryRequest->IdtEntry[i] = (UINT64)((UINT64)IdtEntries[i].HighestPart << 32) |
((UINT64)IdtEntries[i].HighPart << 16) |
(UINT64)IdtEntries[i].LowPart;
}
}
@ -132,7 +132,7 @@ IdtEmulationPrepareHostIdt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
HOST_IDT_DESCRIPTOR_COUNT * sizeof(SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64));
/*
for (size_t i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
for (SIZE_T i = 0; i < HOST_IDT_DESCRIPTOR_COUNT; i++)
{
SEGMENT_DESCRIPTOR_INTERRUPT_GATE_64 CurrentEntry = WindowsIdt[i];
@ -198,7 +198,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
//
// Store the latest exception vector
//
VCpu->LastExceptionOccuredInHost = IntrTrapFrame->vector;
VCpu->LastExceptionOccurredInHost = IntrTrapFrame->vector;
switch (IntrTrapFrame->vector)
{
@ -217,7 +217,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
if (!VmxBroadcastHandleNmiCallback((PVOID)IntrTrapFrame, FALSE))
{
//
// We cannot just use the NMI Window Exiting here becasue
// We cannot just use the NMI Window Exiting here because
// in certain scenarios, VMRESUME with Error 0x7 will happen
// Which means that the layout of the VMCS is wrong
//
@ -258,7 +258,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
//
// host page-fault
//
PageFaultCr2 = __readcr2();
PageFaultCr2 = CpuReadCr2();
LogInfo("Page-fault received, rip: %llx, rsp: %llx, error: %llx, CR2: %llx",
IntrTrapFrame->rip,
@ -278,6 +278,7 @@ IdtEmulationhandleHostInterrupt(_Inout_ INTERRUPT_TRAP_FRAME * IntrTrapFrame)
IntrTrapFrame->rsp,
IntrTrapFrame->error,
IntrTrapFrame->vector);
DbgBreakPoint();
break;
}
@ -308,7 +309,7 @@ IdtEmulationHandlePageFaults(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// Read the page-fault address
//
__vmx_vmread(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
VmxVmread64P(VMCS_EXIT_QUALIFICATION, &PageFaultAddress);
// LogInfo("#PF Fault = %016llx, Page Fault Code = 0x%x | %s%s%s%s",
// PageFaultAddress,
@ -355,7 +356,8 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
UINT64 GuestRip = NULL64_ZERO;
BYTE TargetMem = NULL_ZERO;
__vmx_vmread(VMCS_GUEST_RIP, &GuestRip);
VmxVmread64P(VMCS_GUEST_RIP, &GuestRip);
MemoryMapperReadMemorySafe(GuestRip, &TargetMem, sizeof(BYTE));
if (!EptCheckAndHandleBreakpoint(VCpu) || TargetMem == 0xcc)
@ -433,7 +435,7 @@ IdtEmulationHandleExceptionAndNmi(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
if (VCpu->EnableExternalInterruptsOnContinue ||
VCpu->EnableExternalInterruptsOnContinueMtf ||
VCpu->RegisterBreakOnMtf)
VCpu->InstrumentationStepInMtf)
{
//
// Ignore the nmi
@ -479,7 +481,7 @@ IdtEmulationInjectInterruptWhenInterruptWindowIsOpen(_Inout_ VIRTUAL_MACHINE_STA
// We can't inject interrupt because the guest's state is not interruptible
// we have to queue it an re-inject it when the interrupt window is opened !
//
for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
{
//
// Find an empty space
@ -516,11 +518,11 @@ IdtEmulationHandleExternalInterrupt(_Inout_ VIRTUAL_MACHINE_STATE * VCpu,
//
// In order to enable External Interrupt Exiting we have to set
// PIN_BASED_VM_EXECUTION_CONTROLS_EXTERNAL_INTERRUPT in vmx
// IA32_VMX_PINBASED_CTLS_EXTERNAL_INTERRUPT_EXITING_FLAG in vmx
// pin-based controls (PIN_BASED_VM_EXEC_CONTROL) and also
// we should enable VM_EXIT_ACK_INTR_ON_EXIT on vmx vm-exit
// controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function might not
// always be successful if the guest is not in the interruptible
// we should enable IA32_VMX_EXIT_CTLS_ACKNOWLEDGE_INTERRUPT_ON_EXIT_FLAG
// on vmx vm-exit controls (VMCS_CTRL_VMEXIT_CONTROLS), also this function
// might not always be successful if the guest is not in the interruptible
// state so it wait for and interrupt-window exiting to re-inject
// the interrupt into the guest
//
@ -675,7 +677,7 @@ IdtEmulationHandleInterruptWindowExiting(_Inout_ VIRTUAL_MACHINE_STATE * VCpu)
//
if (!InjectPageFault)
{
for (size_t i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
for (SIZE_T i = 0; i < PENDING_INTERRUPTS_BUFFER_CAPACITY; i++)
{
//
// Find an empty space

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