The Depths of Windows Virtualization (Part 2) — Memory Even the Kernel Cannot See: How VBS, HVCI, and Credential Guard Work
· Updated: · Go Komura · Windows, Virtualization, Security, VBS, HVCI, Credential Guard
Revision history (2 updates, last updated Sep 7, 2026)
A log of the changes made to this article. Where a pre-update version was archived, it stays readable at a permanent DOI link.
- Restored the clean-install condition in the search description: VBS is enabled by default on a clean install to compatible hardware, as the Japanese original states. The article body is unchanged. Read the version before this update (DOI: 10.5281/zenodo.22615752)
- Retranslated as a full translation of the current Japanese original. The previous English version was an abridgement that dropped subsections, tables, diagrams, and paragraphs; all of them have been restored to match the Japanese article, and the knowledge map section has been added where the Japanese article has one. The technical claims are the same as in the Japanese version. Read the version before this update (DOI: 10.5281/zenodo.22170925)
- First published
Cite this article(DOI: 10.5281/zenodo.22170924)
This article is archived on Zenodo. Below are both the DOI that always resolves to the latest version and the DOI pinned to the version you are reading.
Go Komura (2026). The Depths of Windows Virtualization (Part 2) — Memory Even the Kernel Cannot See: How VBS, HVCI, and Credential Guard Work. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22170924 https://comcomponent.com/en/blog/windows-virtualization-internals-vbs-hvci-credential-guard/
- DOI (latest version)
- 10.5281/zenodo.22170924
- DOI (this version)
- 10.5281/zenodo.22626872
Where does Windows keep secrets that neither an administrator nor the kernel can read? Part 2 starts from this question and follows how VBS, HVCI, and Credential Guard work.
On traditional Windows, an attacker who loaded a kernel driver as administrator and dumped the memory of the LSASS process could steal password hashes and Kerberos tickets and use them for lateral movement to other machines.
On Windows 11 with Credential Guard running, the hashes of protected domain credentials are not kept anywhere the ordinary kernel can search. On devices that meet the license requirements (Enterprise, Education, and the like) and the hardware requirements, this protection is enabled by default from 22H2 onward.1 The requirements and the actual running state are two different things, so the danger has not gone away wherever it is not running.
Part 1 showed the structure in which the host Windows runs in the root partition on top of the hypervisor. What this article follows is one more boundary line, drawn inside that same partition.
“The Depths of Windows Virtualization” — All 3 Parts
We look at the same Windows hypervisor in the order foundation → security isolation → application to lightweight VMs.
| Part | Central question |
|---|---|
| Part 1: The Hypervisor and Partitions | Where does the host Windows run? |
| Part 2: VBS, HVCI, and Credential Guard (this article) | Where are secrets kept that even the kernel cannot read? |
| Part 3: WSL2, Windows Sandbox, and Containers | Why can it be made light while keeping isolation? |
What This Article Assumes
| Item | Details |
|---|---|
| Intended readers | Developers and operators who want to understand what Core isolation, Memory integrity, and Credential Guard actually are |
| Environment | x64 Windows 10/11 or current Windows Server. The discussion of rings and SLAT assumes x64; Arm64 uses different mechanisms such as exception levels |
| Background knowledge | The concepts of partitions and SLAT from Part 1 |
| Difficulty and scope | Intermediate. This is not a configuration guide; it explains the structure of the security features |
How to Read This Article
| What you want to know | Sections to read |
|---|---|
| Why isolation stronger than the kernel is needed, and how it is achieved | The limits of the traditional model in Section 2 → VSM, VTLs, and SLAT in Section 3 |
| What HVCI and Credential Guard each protect | Code integrity in Section 4 → Credentials and protection scope in Section 5 |
| How to tell the settings screen apart from the actual running state | How to check in Section 6 → Misreadings in Section 7 |
1. The Bottom Line First
Windows added an axis of privilege called the VTL (Virtual Trust Level) and put the secrets in VTL1. The ordinary kernel running in VTL0 cannot read VTL1 memory. What guards the boundary is not the kernel itself but the hypervisor, which holds the SLAT translation tables.
That is the skeleton of virtualization-based security (VBS). VBS uses the hypervisor to create an isolated environment and houses security features there. It is designed on the premise that the isolated environment stays protected even if the kernel is compromised.2
flowchart TB
accTitle: The two worlds VBS creates
accDescr: VTL0 and VTL1 sit inside the same partition; VTL0 holds the ordinary kernel and apps, VTL1 holds the Secure Kernel and isolated security features, and the hypervisor guards the boundary
subgraph vtl0 ["VTL0 (the ordinary world)"]
apps["Apps (ring 3)"]
ntk["NT kernel and drivers (ring 0)"]
end
subgraph vtl1 ["VTL1 (the isolated world)"]
ium["Isolated security features"]
sk["Secure Kernel"]
end
hv["Hypervisor (enforces the boundary via SLAT)"] --- vtl0
hv --- vtl1
ntk -.->|Cannot read| ium
Figure 1: There are two worlds inside one Windows, and the VTL0 kernel cannot access VTL1 memory.
The important point is that this is not “standing up another VM”. VTL0 and VTL1 are inside the same partition, inside the same Windows. We look in turn at how this split is achieved.
In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (22 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle
2. The Limits of the Ring Model — The Guardian and the Guarded Stand at the Same Height
Traditional Windows security was built on the ladder of rings (privilege levels). User mode (ring 3) is guarded by kernel mode (ring 0). So who guards ring 0? No one can. Ring 0 is the highest privilege.
This structure has two structural weaknesses.
- The kernel is not a monolith. At ring 0, not only Windows itself but a large number of third-party drivers run. If any one of them has a vulnerability, the attacker obtains code execution at ring 0.
- From ring 0, everything is visible. However well a user-mode process such as LSASS defends itself, an attacker who has taken over the kernel can read its memory freely. Protection attributes and page tables alike are managed by the kernel itself.
flowchart TB
accTitle: The credential-theft path in the traditional ring model
accDescr: An attacker who takes over ring 0 through a vulnerable driver can read LSASS process memory with the kernel's full authority and obtain password hashes
mal["Attacker's code"] -->|Exploits a vulnerable driver| r0["Takes over ring 0"]
r0 --> readall["Can read all physical memory"]
readall --> lsass["Obtains hashes from LSASS memory"]
lsass --> lateral["Abused for lateral movement to other machines"]
Figure 2: Because the guardian (the kernel) and the guarded (the secrets) stand at the same height, the fundamental weakness is that if ring 0 falls, everything falls.
What is needed, then, is “a place higher than ring 0”. That place already appeared in Part 1. The hypervisor runs at a higher privilege than the kernel and takes exclusive control of the CPU’s memory-access permissions (SLAT) early on. An isolated region guarded by the hypervisor is protected even against access from ring-0 (supervisor-mode) OS software.3
3. VSM and VTLs — Adding One More Axis of Privilege
This section proceeds in the order the feature set that provides the isolation (VSM) → the levels of isolation (VTLs) → the mechanism that enforces the boundary (SLAT) → the code that runs inside. The names look alike, but they are not the same thing.
3.1. Virtual Trust Levels (VTLs)
The set of hypervisor features that provides this isolation is called VSM (Virtual Secure Mode). VSM is the foundation for Device Guard, Credential Guard, the virtual TPM, and the like.3
The central concept of VSM is the VTL (Virtual Trust Level). The key points are as follows.3
- VTLs are hierarchical, and the higher the number, the higher the privilege. VTL0 is the lowest; VTL1 is more privileged than VTL0.
- Architecturally up to 16 levels are defined, but what is currently implemented is two: VTL0 and VTL1.
- Each VTL has its own independent memory access protections. The hypervisor manages these protections over the partition’s physical address space, so system software inside the partition cannot change them.
- A virtual processor has separate register state and interrupt machinery per VTL, and a lower VTL cannot peek at a higher VTL’s state.
flowchart TB
accTitle: The three independent pieces that make up VTL isolation
accDescr: Memory access protections, virtual-processor register state, and the interrupt machinery are independent per VTL, and a lower VTL cannot touch any of them in a higher VTL
vtl["What is independent per VTL"] --> m1["Memory access protections"]
vtl --> m2["Virtual-processor register state"]
vtl --> m3["Interrupt machinery"]
m1 -.-> rule["A lower VTL cannot touch a higher VTL"]
m2 -.-> rule
m3 -.-> rule
Figure 3: Making not only memory but also CPU state and interrupts a separate world is the three-piece set that leaves no peephole.
If rings (0 and 3) are the axis that separates “OS and apps”, VTLs are a second axis that separates “the ordinary world and the isolated world”. The two axes are orthogonal, and inside VTL1 there is a kernel mode and a user mode as well.
flowchart TB
accTitle: The four regions created by the two axes of rings and VTLs
accDescr: The ring axis separates kernel mode from user mode, the VTL axis separates the ordinary world from the isolated world, and the combination produces four regions: ordinary apps, the NT kernel, IUM trustlets, and the Secure Kernel
subgraph ax0 ["VTL0 (ordinary world)"]
a0["Ring 3: ordinary apps"]
k0["Ring 0: NT kernel and drivers"]
end
subgraph ax1 ["VTL1 (isolated world)"]
a1["Ring 3: IUM (trustlets)"]
k1["Ring 0: Secure Kernel"]
end
a0 --- k0
a1 --- k1
k0 ~~~ a1
Figure 4: There are now two axes of privilege, and “is it the kernel?” and “is it the isolated world?” became separate questions.
3.2. The Substance of the Boundary Is SLAT
Part 1 said that the second-level translation tables that map guest physical addresses (GPAs) onto actual RAM (SPAs), that is, SLAT, are held by the hypervisor. VSM uses exactly this property. VTL isolation is built using the Hyper-V hypervisor and SLAT.4
When VTL1 declares “this memory is not to be shown to VTL0”, the hypervisor removes the access permission for that page from VTL0’s translation tables. From then on, even if the VTL0 kernel tries to touch that address, it is refused at the CPU’s address-translation stage. It does not matter how the kernel rewrites its own page tables.
The page tables (GVA→GPA) may belong to the kernel, but the translation beyond them (GPA→SPA) and the final access permission belong to the hypervisor.
flowchart TB
accTitle: How an access from VTL0 to VTL1 memory is refused
accDescr: When the VTL0 kernel tries to read VTL1 memory, it can pass its own page tables but is refused by the SLAT access protection, and control transfers to the hypervisor
try["VTL0 kernel tries to read a VTL1 page"] --> pt["Passes the kernel's own page tables"]
pt --> slat{"Does the SLAT access protection allow it?"}
slat -->|Not allowed| deny["Hypervisor intervenes and refuses the access"]
slat -->|Allowed| ok["Ordinary memory access"]
deny -.-> point["Protected at a layer the kernel cannot change"]
Figure 5: The barrier sits outside the kernel, and the SLAT protection cannot be changed by software inside the partition.
Part 1 of the memory series said that “the VAD, the PTE, and the protection attributes decide whether an access is allowed”. In a VBS environment the picture becomes: after all of those have been passed, a SLAT checkpoint is still waiting.
3.3. The Secure Kernel and IUM
What runs inside VTL1 is not the ordinary NT kernel but a small kernel called the Secure Kernel. User mode in VTL1 is called IUM (Isolated User Mode), and the programs that run there are called trustlets (trusted processes).4
A trustlet cannot do anything it likes the way an ordinary process can. Most of its system calls are marshaled to the NT kernel on the VTL0 side, which is asked to do the work.4 VTL1 is not an “upper world that can do anything”; it is deliberately built small, as a vault that holds secrets. The less code that can be brought into the vault, the smaller the attack surface.
flowchart TB
accTitle: The flow of a trustlet's system calls
accDescr: A trustlet in VTL1 does not handle most system calls itself; it marshals them to the VTL0 NT kernel and receives only the result, which keeps VTL1 small
tl["Trustlet (IUM in VTL1)"] --> sc{"A system call is needed"}
sc -->|In most cases| mar["Asks the VTL0 NT kernel"]
mar --> res["Receives only the result"]
res -.-> small["VTL1 stays small and the attack surface shrinks"]
Figure 6: The vault has no facilities of its own; it sends the chores outside and keeps guarding only the secrets.
4. HVCI — Verifying Kernel Code Integrity in the Vault
The two things to grasp about HVCI are where the verification is performed and what is allowed on memory after verification. We look at that protection first, then at its effect on driver compatibility.
4.1. What Is Being Verified
The first representative feature that sits on VBS is Memory integrity, that is, HVCI (hypervisor-protected code integrity). Windows has a code-integrity mechanism that inspects kernel-mode drivers and binaries before they start and refuses to load unsigned or untrusted ones. HVCI performs this verification inside VBS’s isolated environment.2
The reason for moving the verification logic itself into VTL1 is exactly the weakness in Section 2. If the verification code sits inside the VTL0 kernel, an attacker who has taken over the kernel can swap the verification out. If it is in VTL1, the swapping hand cannot reach it.
flowchart TB
accTitle: The difference made by where the verification code lives
accDescr: If the verification code sits inside the VTL0 kernel it is disabled once the kernel is taken over, but if it is in VTL1 even an attacker who has taken over the kernel cannot reach it and the verification stays protected
atk["Attacker who has taken over the kernel"] --> q{"Where does code-integrity verification live?"}
q -->|"Inside the VTL0 kernel (traditional)"| bad["The verification logic can be swapped out"]
q -->|"Isolated environment in VTL1 (HVCI)"| good["The swap is out of reach"]
bad --> res1["Unsigned code can run in the kernel"]
good --> res2["Verification keeps working after the kernel is compromised"]
Figure 7: Do not put the checkpoint inside the side that might be breached; that relocation of the verification logic is the essence of HVCI.
4.2. The Rules for Executable Pages
HVCI’s effect is not limited to “inspection at startup”. It also constrains kernel-memory allocation.5
- A kernel page becomes executable only after it has passed code-integrity verification.
- An executable page never becomes writable (so-called W^X).
With these two in place, even if a vulnerability such as a buffer overflow lets you rewrite kernel memory, you cannot get the rewritten contents executed. Executable pages cannot be rewritten, and pages that can be rewritten cannot be executed.5 The final backing for execute permission is the execute right on the SLAT side, which the VTL0 kernel cannot manipulate.
flowchart TB
accTitle: Until a kernel page becomes executable in an HVCI environment
accDescr: A driver-load request receives code-integrity verification in VBS's isolated environment; if it passes it is allowed as an executable, non-writable page, and if it fails it is blocked and recorded in the CodeIntegrity log
load["Request to load and execute kernel code"] --> verify{"Code-integrity verification in the isolated environment"}
verify -->|Pass| exec["Allowed as an executable page (writes forbidden)"]
verify -->|Fail| block["Load blocked"]
block --> log["Recorded in the CodeIntegrity Operational log (event ID 3087)"]
exec -.-> wx["Writable pages stay non-executable"]
Figure 8: The rule that never lets execute and write coexist is verified on the VTL1 side, and the VTL0 kernel cannot overturn it.
Tracing this from the attacker’s point of view shows clearly how the rule takes effect.
flowchart TB
accTitle: How code injection fails in an HVCI environment
accDescr: Even if a vulnerability lets you rewrite kernel memory, a page you could write is not executable, and an executable page cannot be rewritten in the first place, so the injected code can never be executed
inj["Try to tamper with kernel memory via a vulnerability"] --> which{"Which page is the target?"}
which -->|A writable page| wok["The rewrite succeeds"]
which -->|An executable page| xfail["The rewrite itself is impossible"]
wok --> nx["But that page is not executable"]
nx --> dead["The injected code cannot be executed"]
xfail --> dead
Figure 9: Whichever entrance you take, you hit a dead end; that is the point of never letting writable pages and runnable pages overlap.
4.3. The Price: Driver Compatibility
This rule collides with older-design drivers. Drivers that rewrite their own code at run time, have no signature, or demand memory that is both executable and writable cannot be loaded in an HVCI environment.
The fact of the block can be confirmed in Event Viewer under Applications and Services Logs\Microsoft\Windows\CodeIntegrity\Operational (event ID 3087 is the representative one).6
In many cases, this is what is really behind the complaint “after I enabled Memory integrity, a peripheral stopped working”. The proper fix is to update to an HVCI-compatible version of the driver; disabling Memory integrity should be regarded as a last resort that gives up the protection wholesale.
If you are involved in this verification from the driver-development side, see also the filter-driver article (“Windows Minifilter Drivers”).
flowchart TB
accTitle: Triage when a peripheral stops working under Memory integrity
accDescr: Identify the blocked driver in the CodeIntegrity Operational log; the proper fix is to update to an HVCI-compatible version, ask the vendor if none exists, and treat disabling as a last resort that is never made a permanent setting
sym["A device stops working after Memory integrity is enabled"] --> log2["Identify the blocked driver in the CodeIntegrity log"]
log2 --> upd{"Is there an HVCI-compatible driver?"}
upd -->|Yes| fix2["Update and resolve it while leaving HVCI on"]
upd -->|No| ask2["Ask the vendor for a compatible version"]
ask2 -.-> temp["Disabling is a last resort, never a permanent setting"]
Figure 10: The first thing to look at is not the settings screen but the log, and event ID 3087 knows which driver was blocked.
5. Credential Guard — The Hashes Are Inside LSAIso
Where HVCI guards the kernel’s code integrity, Credential Guard guards credentials. Think of the front desk that accepts authentication and the place where the secrets are kept as two separate things, and the structure and the protection scope fall into place.
5.1. LSASS and LSAIso
The second representative feature that sits on VBS is the answer to the opening mystery: Credential Guard.
Traditional Windows kept NTLM hashes and Kerberos tickets in the memory of the LSA process (lsass.exe). When Credential Guard is enabled, the storage of the protected secrets among these, such as the NTLM hashes of domain credentials and Kerberos TGTs (Ticket Granting Tickets), moves to LSAIso.exe, a trustlet that runs in IUM in VTL1.7
- lsass.exe (VTL0) keeps running as the front desk for authentication processing, as before.
- The actual secrets are held by LSAIso.exe (VTL1) and cannot be accessed from VTL0.
- The two communicate via RPC (Remote Procedure Call).
- LSAIso hosts no device drivers at all and houses only the minimum set of signed binaries. The signatures are verified against a certificate that VBS trusts.7
flowchart TB
accTitle: Where credentials sit when Credential Guard is enabled
accDescr: lsass in VTL0, as the authentication front desk, communicates with LSAIso in VTL1 via RPC; the actual hashes and TGTs of protected domain credentials are held by LSAIso, so an attacker who gains administrator privileges in VTL0 and dumps lsass still does not get the protected secrets themselves
subgraph v0 ["VTL0"]
lsassP["lsass.exe (authentication front desk)"]
att["Attacker (administrator privileges)"]
end
subgraph v1 ["VTL1"]
iso["LSAIso.exe (vault for the secrets)"]
end
lsassP <-->|RPC| iso
att -->|Memory dump| lsassP
att -.->|Cannot reach| iso
Figure 11: Because the front desk and the vault were separated, dumping lsass no longer yields the actual hashes of the protected domain credentials.
Conditions for Being Enabled by Default
From Windows 11 version 22H2 onward, VBS and Credential Guard are enabled by default on devices that meet the license requirements (Enterprise E3/E5, Education A3/A5) and the hardware requirements. On editions such as Pro, Credential Guard is not enabled automatically (there are exceptions, such as a machine that was enabled under a qualifying license in the past and was later downgraded).1
This credential protection is not a matter of a special add-on product; it is the standard state of current Windows on the qualifying editions.
flowchart TB
accTitle: The flow of credentials from sign-in to authentication
accDescr: After sign-in the actual secrets are stored in LSAIso in VTL1; each time authentication is needed, lsass in VTL0 requests the computation via RPC, and only the result of the authentication processing comes back to VTL0 without the protected long-term secrets themselves ever being returned
signin["User signs in"] --> front["lsass handles it as the front desk"]
front --> store["The actual secrets are stored in LSAIso"]
auth["Later authentication requests"] --> front
front -->|Requests the computation via RPC| store
store -->|"Returns the result (never the secret)"| front
Figure 12: The protected long-term secrets themselves never leave the vault; what returns to VTL0 is the result of the authentication processing, such as a ticket.
5.2. Know Precisely What Is Not Protected
Credentials That Are Protected
Credential Guard is not an all-purpose shield. What it protects is the NTLM hashes of domain credentials, Kerberos TGTs (Ticket Granting Tickets), and anything stored as domain credentials.
Out of Scope
The following are out of scope.8
- Kerberos service tickets (TGTs are protected)
- The credentials of local accounts and Microsoft accounts
- Theft of input by a keylogger, and physical attacks
- Credentials on paths that use NTLMv1, MS-CHAPv2, Digest, or CredSSP
- The internals of third-party software that manages credentials on its own
Separately from the Protection Scope, Check Authentication Compatibility Too
Also, when Credential Guard is enabled, NTLMv1, unconstrained Kerberos delegation, and the like can no longer be used, so business systems that depend on legacy authentication need a compatibility check.8 It is not “enable it and you are done”; understand what is inside and outside the protection scope and fill the rest with other controls. That is the correct way to use it in practice.
flowchart TB
accTitle: Credential Guard's protection scope
accDescr: Domain NTLM hashes and TGTs and stored domain credentials are protected, while service tickets, local accounts, keyloggers, physical attacks, and credentials an app stores on its own are out of scope
scope{"Which side of the protection scope is this secret on?"} --> inA["Domain NTLM hashes and TGTs"]
scope --> outA["Service tickets and local accounts"]
inA --> prot["Protected in LSAIso"]
outA --> unprot["Not protected (other controls are needed)"]
unprot -.-> outB["Keystrokes, physical attacks, and app-private stores are also out of scope"]
Figure 13: The protection scope is drawn with a clear line, and the outside of the line is filled with multi-factor authentication and app-side design.
6. See It for Yourself
You can check the running state of VBS and of each feature on your own machine. Read the state of VBS, the foundation, separately from the state of the services that run on top of it.
6.1. Check VBS and the Running Services in PowerShell
Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard `
-ClassName Win32_DeviceGuard |
Select-Object VirtualizationBasedSecurityStatus,
SecurityServicesConfigured,
SecurityServicesRunning
Read the output as follows.9
- If
VirtualizationBasedSecurityStatusis 2, VBS is enabled and running. - If
SecurityServicesRunningcontains 1, Credential Guard is running; if it contains 2, Memory integrity (HVCI) is running.
6.2. Read msinfo32 and the Settings Screen Differently
To check the running state in a GUI, look at the “Virtualization-based security” field in msinfo32 (the running services are listed there, such as “Hypervisor enforced Code Integrity”).
The “Memory integrity” toggle under “Device security > Core isolation” in the Windows Security app is a screen that reflects the setting. It can look on even while HVCI is not actually running, such as while a reboot is pending right after enablement or when there is a compatibility problem at startup, so judge whether it is running from msinfo32 or from SecurityServicesRunning in Win32_DeviceGuard.6
6.3. Do Not Judge “Running” from the Presence of a Process Alone
There is also a trace on Task Manager’s Details tab. On a machine where VBS is running you will see a process called “Secure System”. LsaIso.exe is the process that appears when the Isolated LSA service is hosted in VTL1, and it does not normally appear in a configuration where only HVCI is enabled.
The presence or absence of a process is only a trace, though, so judge whether Credential Guard is running from SecurityServicesRunning (whether it contains 1), as described above. Both are windows, visible from VTL0, onto the world on the VTL1 side.
flowchart TB
accTitle: The procedure for checking that VBS-related features are running
accDescr: Confirm that VBS is running by querying Win32_DeviceGuard, judge whether Credential Guard and HVCI are running from the SecurityServicesRunning values, and look at the CodeIntegrity log for driver problems
q0["Query Win32_DeviceGuard"] --> q1{"Is the VBS status 2?"}
q1 -->|No| off["VBS not running (check requirements and settings)"]
q1 -->|Yes| q2{"What does SecurityServicesRunning contain?"}
q2 -->|Contains 1| cg["Credential Guard running"]
q2 -->|Contains 2| hvciR["Memory integrity (HVCI) running"]
hvciR -.-> ev["For driver problems, check the CodeIntegrity log (3087)"]
Figure 14: State checking proceeds in three stages: VBS itself, each service on top of it, and the log when a problem occurs.
7. Three Misreadings to Avoid in Practice
7.1. “Protecting administrator privileges is enough. VBS is a server-side story”
What Credential Guard prevents is the spread of damage after administrator privileges have been taken (hash exfiltration and lateral movement). In other words VBS is one layer of defense in depth that assumes compromise, and it is on client PCs that it pays off. On Windows 11 that meets the requirements, enabled by default is the norm, so the right posture is not “this has nothing to do with us” but “manage compatibility on the assumption that it is already running”.
flowchart TB
accTitle: The stages of compromise and where VBS takes effect
accDescr: Initial access is covered by other controls such as multi-factor authentication and training; HVCI blocks the code injection into the kernel that follows privilege escalation; Credential Guard blocks the theft of protected domain secrets and lateral movement, but does not reach secrets outside its scope
s1["Initial access (phishing and the like)"] --> s2["Privilege escalation"]
s2 --> s3["Code injection into the kernel"]
s3 --> s4["Theft of protected domain secrets and lateral movement"]
s1 -.-> d1["MFA, training, and EDR cover this"]
s3 -.-> d2["HVCI blocks this step"]
s4 -.-> d3["Credential Guard blocks this (protected secrets only)"]
Figure 15: VBS is not a “keep them out” technology; it is a “do not let them win once they are in” technology, and the stage it guards is different.
7.2. “If Memory integrity causes a problem, just turn it off”
Turning it off will make things work for the moment, but it removes the barrier against code injection into the kernel wholesale. The proper fix is to first identify the blocked driver in the CodeIntegrity log and then apply the vendor’s updated version. Even when you disable it temporarily for validation, we recommend an operating practice that never makes that a permanent setting.
7.3. “With Credential Guard, passwords cannot be stolen”
That is overconfidence born of confusing the protection scope. Service tickets, local accounts, keystrokes themselves, and credentials that an app stores on its own are out of scope.8 Phishing and keyloggers need other controls (multi-factor authentication, Windows Hello, and a review of how the app itself manages credentials).
8. Summary
- VBS uses the hypervisor to create an isolated environment and protects security features on the assumption that the kernel will be compromised.2
- The unit of isolation is the VTL; currently two levels are implemented, VTL0 (the ordinary world) and VTL1 (the Secure Kernel and IUM).3
- The substance of the boundary is the SLAT memory access protection, which software inside the partition, the kernel included, cannot change.3
- HVCI performs code-integrity verification in the isolated environment and enforces “not executable until verification passes” and “executable pages are not writable”.5 The price is that driver compatibility has to be managed.6
- Credential Guard isolates the NTLM hashes and TGTs of domain credentials in LSAIso in VTL1. From Windows 11 22H2 onward it is enabled by default on devices that meet the license requirements (Enterprise, Education) and the hardware requirements (use this together with a check of the running state).71
- The running state can be checked from SecurityServicesRunning in
Win32_DeviceGuard(1 = Credential Guard, 2 = HVCI).9
Continued in Part 3, “Virtual Machines That Boot in Seconds — WSL2, Windows Sandbox, and Containers”.
So far we have looked at virtualization from the “strength of isolation” side. The final installment looks from the opposite side, “lightness”, and follows where the lightweight VMs that shed the weight of a full VM are cutting corners.
Related Articles
- The Depths of Windows Virtualization (Part 1) — Where Is Your Windows Actually Running? The Hypervisor and Partitions
- The Depths of Windows Memory (Part 1) — The Moment a Virtual Address Becomes Physical RAM: A Page Fault from Start to Finish
- Windows Minifilter Drivers
- Windows Error Code Systems — Win32, HRESULT, and NTSTATUS
Related Consulting Areas
KomuraSoft LLC handles compatibility investigations between Windows applications and security features, analysis of driver-caused failures, and technical validation of in-house PC environments.
- Windows Application Development
- Bug Investigation and Root-Cause Analysis
- Legacy Asset Reuse and Migration
- Contact Us
References
-
Microsoft Learn, Credential Guard overview. On Credential Guard being enabled by default from Windows 11 version 22H2 onward on devices that meet the license, hardware, and software requirements and have not been explicitly disabled; the qualifying editions/licenses being Enterprise (E3/E5) and Education (A3/A5), with Pro out of scope; and a Pro machine that was previously enabled under a qualifying license remaining eligible for enablement by default after a downgrade. ↩ ↩2 ↩3
-
Microsoft Learn, Virtualization-based Security (VBS). On VBS using hardware virtualization and the Windows hypervisor to create an isolated environment and making it the OS’s root of trust on the assumption that the kernel can be compromised; Memory integrity running kernel-mode code-integrity verification inside that isolated environment; and SLAT being a mandatory requirement for VBS. ↩ ↩2 ↩3
-
Microsoft Learn, Virtual Secure Mode. On VSM being the foundation for Device Guard, Credential Guard, the virtual TPM, and the like; access to isolated regions being controlled only through the hypervisor and protected even from ring-0 OS software; VTLs being hierarchical with 2 of a maximum of 16 levels implemented; and per-VTL memory access protections being unchangeable by system software inside the partition. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Isolated User Mode (IUM) Processes. On VSM creating VTLs using the Hyper-V hypervisor and SLAT; the Secure Kernel and IUM running in VTL1; trustlets marshaling system calls to the VTL0 kernel; and LSAIso running in VTL1 and communicating with lsass via RPC. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and virtualization-based security. On Memory integrity (HVCI) performing code-integrity verification in an isolated environment, and on kernel memory pages becoming executable only after passing verification and executable pages never becoming writable. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and VBS enablement. On Memory integrity being enabled by default on a clean install of Windows 11 when the hardware is compatible; checking the state in msinfo32 and the Windows Security app; and confirming a blocked driver via event ID 3087 in the CodeIntegrity Operational log. ↩ ↩2 ↩3
-
Microsoft Learn, How Credential Guard works. On the LSA communicating with the isolated LSA process (LSAIso.exe) to store secrets when Credential Guard is enabled; the stored data being protected by VBS and inaccessible from the rest of the OS; and the isolated LSA process hosting no device drivers and housing only a minimum set of signature-verified binaries. ↩ ↩2 ↩3
-
Microsoft Learn, Credential Guard protection limits. On service tickets, local accounts, keyloggers, physical attacks, and the like being outside Credential Guard’s protection scope; TGTs being protected while service tickets are not; and NTLMv1 and unconstrained delegation becoming unusable when it is enabled. ↩ ↩2 ↩3
-
Microsoft Learn, Enable virtualization-based protection of code integrity. On how to check the state of VBS and Memory integrity via the Win32_DeviceGuard class, and on the meaning of the SecurityServicesRunning values (1 is Credential Guard, 2 is Memory integrity). ↩ ↩2
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
Does Turning Off Memory Integrity (HVCI) Make Windows Faster? — What It Means, How to Do It, and How to Decide
Does turning off Memory integrity (HVCI) really speed up a Windows PC? When it can help, when it cannot, how to switch it off and back, a...
The Depths of Windows Virtualization (Part 3) — Virtual Machines That Boot in Seconds: Why WSL2, Windows Sandbox, and Containers Are So Light
Why WSL2 and Windows Sandbox boot in seconds and stay light: dynamic base images, direct map, dynamic memory allocation, and Hyper-V isol...
The Depths of Windows Virtualization (Part 1) — Where Is Your Windows Actually Running? The Hypervisor and Partitions
When you enable Hyper-V, the host Windows itself runs as the root partition on top of the hypervisor. This article explains the foundatio...
Named Pipes in Practice — Windows' Standard IPC from Design to Security
A practical guide to named pipes, Windows' standard IPC. Covers byte vs. message mode, servers that handle multiple clients, ACL and impe...
Choosing a Windows Service Account — LocalSystem, Virtual Accounts, and gMSA
Still running Windows services as LocalSystem? Compare LocalService, NetworkService, virtual accounts, domain users, and gMSA by privileg...
Related Topics
These topic pages place the article in a broader service and decision context.
Windows Technical Topics
Topic hub for KomuraSoft LLC's Windows development, investigation, and legacy-asset articles.
Where This Topic Connects
This article connects naturally to the following service pages.
Windows App Development
We support Windows desktop applications that involve resident processing, device integration, operational logging, and maintainable structure.
Frequently Asked Questions
Common questions about the topic of this article.
- Are VBS (virtualization-based security) and Core isolation the same thing?
- Strictly speaking, they are different. VBS is the foundational technology that uses the hypervisor to create an isolated environment, and "Core isolation" in the Windows Security app is the name of a screen that groups several protections built on top of VBS. The representative one is "Memory integrity", which refers to HVCI (hypervisor-protected code integrity). Confirm the running state of each individual service by querying Win32_DeviceGuard, not from what the screen shows.
- Can VTL1 memory really not be read, even with administrator privileges or from a kernel driver?
- It cannot. The per-VTL memory access protections are managed by the hypervisor over the partition's physical address space, and software running inside the partition cannot change them. Even code running in the kernel (ring 0) is not permitted to access VTL1 memory from VTL0.
- Why can enabling Memory integrity (HVCI) stop a driver from working?
- In an HVCI environment, a kernel page becomes executable only after it has passed integrity verification, and writes to executable pages are not permitted. An unsigned driver, or an older-design driver that rewrites executable memory, cannot satisfy this constraint, so its load is blocked. You can confirm the block in the CodeIntegrity Operational log (event ID 3087 and the like).
- What does Credential Guard protect, and what does it not protect?
- It protects, in an isolated environment, the NTLM password hashes of domain credentials, Kerberos TGTs, and anything an app has stored as domain credentials. Kerberos service tickets, the credentials of local accounts and Microsoft accounts, theft of input by a keylogger, and physical attacks are out of scope.
- Where can I check whether VBS is running?
- Look at the "Virtualization-based security" field in msinfo32, or query the Win32_DeviceGuard class in the root/Microsoft/Windows/DeviceGuard namespace from PowerShell. If SecurityServicesRunning contains 1, Credential Guard is running; if it contains 2, Memory integrity (HVCI) is running.