Bitdefender Hypervisor Memory Introspection
winguest.c File Reference
#include "winguest.h"
#include "callbacks.h"
#include "cr_protection.h"
#include "decoder.h"
#include "drivers.h"
#include "dtr_protection.h"
#include "guests.h"
#include "introcpu.h"
#include "msr_protection.h"
#include "swapgs.h"
#include "swapmem.h"
#include "vecore.h"
#include "winagent.h"
#include "winapi.h"
#include "winguest_supported.h"
#include "winhal.h"
#include "winidt.h"
#include "winpe.h"
#include "winpfn.h"
#include "winprocesshp.h"
#include "hook.h"
#include "exceptions.h"
#include "alerts.h"
#include "winthread.h"
#include "winsud.h"
#include "winintobj.h"

Go to the source code of this file.

Macros

#define KERNEL_SEARCH_LIMIT   (16 * ONE_MEGABYTE)
 The maximum size of the area of memory in which the kernel base is searched for. More...
 
#define IDLE_THREAD_OFFSET_PCR   ((gGuest.Guest64) ? 0x198 : 0x12C)
 The offset of the IdleThread field inside the _KPCR. More...
 
#define PROCESS_SEARCH_LIMIT_THREAD_UPPER   (DWORD)((gGuest.Guest64) ? 0x220 : 0x150)
 The upper limit of the area in which the idle process is searched. More...
 
#define PROCESS_SEARCH_LIMIT_THREAD_LOWER   (DWORD)((gGuest.Guest64) ? 0x210 : 0x150)
 The lower limit of the area in which the idle process is searched. More...
 
#define CR3_OFFSET_IN_KPROCESS   (DWORD)((gGuest.Guest64) ? 0x28 : 0x18)
 The offset of the DirectoryTableBase field inside _KPROCESS. More...
 
#define WIN_SHARED_USER_DATA_OFFSET_PRODUCT   0x264
 

Functions

static INTSTATUS IntWinGuestFindKernelObjectsInternal (void)
 Finds all the objects of interest from the Windows kernel. More...
 
static INTSTATUS IntWinGuestFindKernelObjects (void)
 Searches for kernel objects. More...
 
static INTSTATUS IntWinGuestFindSelfMapIndex (void)
 Finds the self map index. More...
 
static BOOLEAN IntWinGuestIsSystemCr3 (QWORD KernelAddress, const VA_TRANSLATION *GvaTranslation, QWORD Cr3)
 Checks if a Cr3 is the system Cr3. More...
 
static INTSTATUS IntWinGuestFindSystemCr3 (QWORD KernelAddress, QWORD *SystemCr3, QWORD StartPhysical, QWORD EndPhysical)
 Searches for the system Cr3 in a range of physical addresses. More...
 
void IntWinGuestCancelKernelRead (void)
 Cancels the kernel read. More...
 
INTSTATUS IntWinGuestInit (void)
 Initializes a new Windows guest. More...
 
void IntWinGuestUninit (void)
 Uninits a Windows guest. More...
 
INTSTATUS IntWinGuestActivateProtection (void)
 Activates the protection for a Windows guest. More...
 
static INTSTATUS IntWinGuestResolveImports (void)
 Obtains the addresses of public variable and functions exposed by the Windows kernel. More...
 
static INTSTATUS IntWinGuestFetchProductType (WIN_PRODUCT_TYPE *ProductType)
 Obtains the Windows product type. More...
 
static INTSTATUS IntWinGuestFinishInit (void)
 Finalizes the Windows initialization once the entire kernel is read. More...
 
static INTSTATUS IntWinGuestSectionInMemory (WIN_INIT_SWAP *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
 Handles the swap in of a kernel section done while the WINDOWS_GUEST.KernelBuffer is read. More...
 
static INTSTATUS IntWinGuestReadKernel (PBYTE KernelHeaders)
 Reads the whole kernel image in memory, including swapped-out sections. More...
 
static INTSTATUS IntWinGuestKernelHeadersInMemory (WIN_INIT_SWAP *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
 Handles the swap in of the kernel MZPE headers. More...
 
static INTSTATUS IntWinGuestFindBuildNumber (QWORD KernelGva, BOOLEAN Guest64, BOOLEAN IsKptiInstalled, DWORD *NtBuildNumber)
 Finds the NtBuildNumber kernel variable. More...
 
static INTSTATUS IntWinGuestValidateKernel (QWORD KernelBase, QWORD KernelGva, BYTE *KernelHeaders)
 Validates if the presumed kernel base is the real kernel base, based on various checks. More...
 
static INTSTATUS IntWinGuestFindKernel (QWORD KernelGva, QWORD *KernelBase)
 Searches for the base of the Windows kernel image. More...
 
static DWORD IntWinGetActiveCpuCount (DWORD CpuCount)
 Gets the number of active CPUs used by the guest. More...
 
static INTSTATUS IntWinGuestFindKernelCr3 (QWORD Syscall)
 Searches for the kernel Cr3. More...
 
INTSTATUS IntWinGuestFindIdleCr3 (void)
 Searches the Cr3 used by the idle process. More...
 
INTSTATUS IntWinGuestNew (void)
 Starts the initialization and protection process for a new Windows guest. More...
 
INTSTATUS IntWinGetVersionString (DWORD FullStringSize, DWORD VersionStringSize, CHAR *FullString, CHAR *VersionString)
 Gets the version string for a Windows guest. More...
 

Variables

WINDOWS_GUESTgWinGuest = NULL
 Global variable holding the state of a Windows guest. More...
 

Macro Definition Documentation

◆ CR3_OFFSET_IN_KPROCESS

#define CR3_OFFSET_IN_KPROCESS   (DWORD)((gGuest.Guest64) ? 0x28 : 0x18)

The offset of the DirectoryTableBase field inside _KPROCESS.

We also have this information available in WIN_OPAQUE_FIELDS, from CAMI, but we need this offset earlier in the initialization phase, before we know the Windows version, so we can't reliably load any settings from CAMI. Since this offset remained constant on all Windows versions from 7 to 10, it is safe to have it defined here.

Definition at line 69 of file winguest.c.

Referenced by IntWinGuestFindIdleCr3().

◆ IDLE_THREAD_OFFSET_PCR

#define IDLE_THREAD_OFFSET_PCR   ((gGuest.Guest64) ? 0x198 : 0x12C)

The offset of the IdleThread field inside the _KPCR.

This is part of the constant fields of the _KPCR and should not change

Definition at line 55 of file winguest.c.

Referenced by IntWinGuestFindIdleCr3().

◆ KERNEL_SEARCH_LIMIT

#define KERNEL_SEARCH_LIMIT   (16 * ONE_MEGABYTE)

The maximum size of the area of memory in which the kernel base is searched for.

The Windows kernel is around 9MB in size, so setting this to 16MB should be enough

Definition at line 43 of file winguest.c.

Referenced by IntWinGuestFindBuildNumber(), IntWinGuestFindKernel(), and IntWinGuestNew().

◆ PROCESS_SEARCH_LIMIT_THREAD_LOWER

#define PROCESS_SEARCH_LIMIT_THREAD_LOWER   (DWORD)((gGuest.Guest64) ? 0x210 : 0x150)

The lower limit of the area in which the idle process is searched.

Definition at line 61 of file winguest.c.

Referenced by IntWinGuestFindIdleCr3().

◆ PROCESS_SEARCH_LIMIT_THREAD_UPPER

#define PROCESS_SEARCH_LIMIT_THREAD_UPPER   (DWORD)((gGuest.Guest64) ? 0x220 : 0x150)

The upper limit of the area in which the idle process is searched.

Definition at line 58 of file winguest.c.

Referenced by IntWinGuestFindIdleCr3().

◆ WIN_SHARED_USER_DATA_OFFSET_PRODUCT

#define WIN_SHARED_USER_DATA_OFFSET_PRODUCT   0x264

Function Documentation

◆ IntWinGetActiveCpuCount()

static DWORD IntWinGetActiveCpuCount ( DWORD  CpuCount)
static

Gets the number of active CPUs used by the guest.

The number of VCPUs exposed by the hypervisor may not match the actual number of CPUs that the guest will use. This can happen if someone uses the msconfig or the bcdedit utilities to change the number of cores used by the OS. In that case we want to mark the unused cores as not being used (VCPU_STATE.Initialized will be set to False). Any CPU that has its Cr3 set to 0 or has the paging bit in Cr0 cleared is considered to be inactive.

Parameters
[in]CpuCountThe number of VCPUs reported by the integrator
Returns
The actual number of CPUs used by the guest

Definition at line 2011 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGetVersionString()

INTSTATUS IntWinGetVersionString ( DWORD  FullStringSize,
DWORD  VersionStringSize,
CHAR FullString,
CHAR VersionString 
)

Gets the version string for a Windows guest.

Parameters
[in]FullStringSizeThe size of the FullString buffer
[in]VersionStringSizeThe size of the VersionString buffer
[out]FullStringA NULL-terminated string containing detailed version information
[out]VersionStringA NULL-terminated string containing human-readable version information
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_READYif the information is not yet available
INT_STATUS_DATA_BUFFER_TOO_SMALLif any of the buffers is not large enough

Definition at line 2650 of file winguest.c.

Referenced by IntGetVersionString().

◆ IntWinGuestActivateProtection()

INTSTATUS IntWinGuestActivateProtection ( void  )

Activates the protection for a Windows guest.

Depending on the Activation and protection flags used, this will activate various protection mechanisms: IDT, Syscall MSR, Cr4, IDTR, and GDTR. The ProtectionActivated field of gGuest will be set to True.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 737 of file winguest.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinGuestCancelKernelRead()

void IntWinGuestCancelKernelRead ( void  )

Cancels the kernel read.

This function cancels all the pending page faults that were scheduled in order to read the WINDOWS_GUEST.KernelBuffer.

Definition at line 607 of file winguest.c.

Referenced by IntGuestPrepareUninit(), and IntWinGuestNew().

◆ IntWinGuestFetchProductType()

static INTSTATUS IntWinGuestFetchProductType ( WIN_PRODUCT_TYPE ProductType)
static

Obtains the Windows product type.

This information is available in the _KUSER_SHARED_DATA structure

Parameters
[out]ProductTypeThe type of the Windows product
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_NEEDED_HINTfor 32-bit guests, when ProductType is always winProductTypeWinNt
INT_STATUS_INVALID_DATA_VALUEif the type obtained from the guest is not a known good value as described by the WIN_PRODUCT_TYPE enum

Definition at line 958 of file winguest.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinGuestFindBuildNumber()

static INTSTATUS IntWinGuestFindBuildNumber ( QWORD  KernelGva,
BOOLEAN  Guest64,
BOOLEAN  IsKptiInstalled,
DWORD NtBuildNumber 
)
static

Finds the NtBuildNumber kernel variable.

Even if this is exported by the kernel, we may not always be able to obtain its address, since the export directory might be swapped-out. We need its value before reading the WINDOWS_GUEST.KernelBuffer so we also try to find it by applying some invariant rules. It will try to match the found value with one of the supported Windows versions supplied by CAMI.

Parameters
[in]KernelGvaThe guest virtual address of the base of the kernel image
[in]Guest64True for 64-bit guests, False for 32-bit guests
[in]IsKptiInstalledTrue if KPTI is enabled, False if it is not
[out]NtBuildNumberThe value of the NtBuildNumber
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_FOUNDif NtBuildNumber was not found
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available

Definition at line 1631 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestFindIdleCr3()

INTSTATUS IntWinGuestFindIdleCr3 ( void  )

Searches the Cr3 used by the idle process.

This will read the address of the idle thread from the currently loaded _KPCR and then search for the address of the process that owns that thread and get the Cr3 value from that process.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_FOUNDif the Cr3 was not found

Definition at line 2236 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestFindKernel()

static INTSTATUS IntWinGuestFindKernel ( QWORD  KernelGva,
QWORD KernelBase 
)
static

Searches for the base of the Windows kernel image.

This is done by using a guest virtual address that is already known to be in the kernel (like the address of the syscall handler, for example) and searching backwards for a valid MZPE signature. The searched area is limited to KERNEL_SEARCH_LIMIT bytes.

Parameters
[in]KernelGvaA guest virtual address that is known to be inside the kernel image
[out]KernelBaseThe base of the kernel image
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_FOUNDif the kernel base was not found

Definition at line 1932 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestFindKernelCr3()

static INTSTATUS IntWinGuestFindKernelCr3 ( QWORD  Syscall)
static

Searches for the kernel Cr3.

This is done by analyzing the syscall handler and looking for an instruction that loads the cr3 register with a value obtained from the _KPCR (using the gs segment register for 64-bit kernels, and the fs segment register for the 32-bit kernels). The sequence of instructions should be:

mov reg, qword [gs:offset]/dword [fs:offset]
mov cr3, reg

The offset used to access the gs or fs segment is then used to read the kernel Cr3 value from the _KPCR. The _KPCR address is obtained using IntFindKernelPcr.

Parameters
[in]SyscallThe guest virtual address of the syscall handler
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_FOUNDif the kernel cr3 value is not found

Definition at line 2067 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestFindKernelObjects()

static INTSTATUS IntWinGuestFindKernelObjects ( void  )
static

Searches for kernel objects.

This function will delegate a part of the search to IntWinGuestFindKernelObjectsInternal, which will obtain the PsLoadedModuleList and PsActiveProcessHead kernel variables, and the address of the PFN data base. Then, it will use the PsActiveProcessHead to obtain the _EPROCESS address of the system process and read the system Cr3 from it.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available
INT_STATUS_NOT_FOUNDif not all the objects were found

Definition at line 311 of file winguest.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinGuestFindKernelObjectsInternal()

static INTSTATUS IntWinGuestFindKernelObjectsInternal ( void  )
static

Finds all the objects of interest from the Windows kernel.

This searches for the PsLoadedModuleList and PsActiveProcessHead kernel variables, and for the address of the PFN data base. The search is done in the ALMOSTRO and .data sections of the kernel, using the WINDOWS_GUEST.KernelBuffer, if it is available. Since some Windows versions have been observed to have multiple sections with the name ALMOSTRO, the functions tries to account for this, and allocates enough space for multiple sections.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available
INT_STATUS_NOT_FOUNDif not all the objects were found

Definition at line 73 of file winguest.c.

Referenced by IntWinGuestFindKernelObjects().

◆ IntWinGuestFindSelfMapIndex()

static INTSTATUS IntWinGuestFindSelfMapIndex ( void  )
static

Finds the self map index.

In order to map the paging tables, the 64-bit Windows kernel uses the self mapping mechanism. This means that one of the entries in the PML4 paging structure points to itself. This essentially gives access to all the paging structures. The kernel randomizes the index used for the self map entry at boot, but due to the fact that it must map to a kernel virtual address, we know that it must be situated in the upper half of the page table entries, so it is between 256 and 511 (inclusive). The search is easy: we must find an entry that points back to the Cr3 value. On success, the gGuest.Mm.SelfMapIndex variable is set to the value of the self map index used by the OS. We need this for various things, from the self map protection offered by INTRO_OPT_PROT_KM_SELF_MAP_ENTRY, to the PT filtering and #VE agent.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_NEEDED_HINTif the guest is not using 4- or 5-level paging
INT_STATUS_NOT_FOUNDif the value of the self map index is not found

Definition at line 369 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestFindSystemCr3()

static INTSTATUS IntWinGuestFindSystemCr3 ( QWORD  KernelAddress,
QWORD SystemCr3,
QWORD  StartPhysical,
QWORD  EndPhysical 
)
static

Searches for the system Cr3 in a range of physical addresses.

Parameters
[in]KernelAddressThe address of the kernel image
[out]SystemCr3The value of the system Cr3
[in]StartPhysicalThe start of the memory range in which the search will be done
[in]EndPhysicalThe end of the memory range in which the search will be done
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_INVALID_PARAMETER_2if SystemCr3 is NULL
INT_STATUS_NOT_FOUNDif the system cr3 value is not found
Deprecated:
This function is no longer used

Definition at line 537 of file winguest.c.

◆ IntWinGuestFinishInit()

static INTSTATUS IntWinGuestFinishInit ( void  )
static

Finalizes the Windows initialization once the entire kernel is read.

This function is called wen the entire WINDOWS_GUEST.KernelBuffer is read and does the last steps of the initialization. It will resolve the address and values of any global kernel variable and functions and objects needed by introcore, will obtain the Windows product type, will validate that the OS version is supported and will notify the integrator about the detected operating system. It will also set all the needed API hooks, deploy any performance or mitigation agents and obtain the list of processes and kernel modules. If no errors are encountered, at the end it will send an activation notification to the integrator. If any steps can not be done because of an error an appropriate error state will be set and the initialization will be stopped.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_GUEST_OS_NOT_SUPPORTEDif the OS version is not supported

Definition at line 1008 of file winguest.c.

Referenced by IntWinGuestReadKernel(), and IntWinGuestSectionInMemory().

◆ IntWinGuestInit()

INTSTATUS IntWinGuestInit ( void  )

Initializes a new Windows guest.

Any operations that should be done after basic information about the guest is obtained should be done here. Breakpoint exits are enabled here and not in IntCallbacksInit where all the other events are enabled because activating the break point exits earlier may cause a slow boot on Linux OS so this activation step is done by each OS as a custom step in the initialization phase.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 641 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestIsSystemCr3()

static BOOLEAN IntWinGuestIsSystemCr3 ( QWORD  KernelAddress,
const VA_TRANSLATION GvaTranslation,
QWORD  Cr3 
)
static

Checks if a Cr3 is the system Cr3.

Parameters
[in]KernelAddressThe address of the kernel image
[in]GvaTranslationThe translation information for KernelAddress
[in]Cr3Cr3 value to be checked. Must be page aligned.
Return values
Trueif Cr3 is the system Cr3
Falseif is not
Deprecated:
This function is no longer used

Definition at line 431 of file winguest.c.

Referenced by IntWinGuestFindSystemCr3().

◆ IntWinGuestKernelHeadersInMemory()

static INTSTATUS IntWinGuestKernelHeadersInMemory ( WIN_INIT_SWAP Context,
QWORD  Cr3,
QWORD  VirtualAddress,
QWORD  PhysicalAddress,
void *  Data,
DWORD  DataSize,
DWORD  Flags 
)
static

Handles the swap in of the kernel MZPE headers.

This is the IntSwapMemRead callback set by IntWinGuestNew in order to get the kernel MZPE headers in memory and start the read of the kernel image. It will pause the VCPUs while running in order to ensure the consistency of the data.

Parameters
[in]ContextThe init swap handle used for the headers
[in]Cr3Ignored
[in]VirtualAddressIgnored
[in]PhysicalAddressIgnored
[in]DataThe data read from the guest. This buffer is valid until this function returns.
[in]DataSizeIgnored
[in]FlagsIgnored
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1572 of file winguest.c.

Referenced by IntWinGuestNew().

◆ IntWinGuestNew()

INTSTATUS IntWinGuestNew ( void  )

Starts the initialization and protection process for a new Windows guest.

This will find the base of the kernel, initiate the WINDOWS_GUEST.KernelBuffer read, will start to look for relevant kernel objects, variables, and functions and will activate protection when every needed piece of information is known. The initialization depends on the value of the syscall MSR (for 64-bit guests) or the sysenter MSR (for 32-bit guests) as it will point inside the kernel image and we need a valid address that points somewhere inside the kernel image. Parts of the initialization may be done asynchronously.

Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_INITIALIZEDif the sysenter or syscall MSR does not point inside the kernel space
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available

Definition at line 2346 of file winguest.c.

Referenced by IntGuestHandleCr3Write().

◆ IntWinGuestReadKernel()

static INTSTATUS IntWinGuestReadKernel ( PBYTE  KernelHeaders)
static

Reads the whole kernel image in memory, including swapped-out sections.

This will allocate and fill WINDOWS_GUEST.KernelBuffer. For the swapped-out sections, IntSwapMemRead will be used with IntWinGuestSectionInMemory as the swap-in handler. Discardable sections will be filled with 0, as those can not be brought back into memory. The same thing will be done for the INITKDBG and ERRATA sections. If all the sections are already present in memory, this function will finalize the initialization calling IntWinGuestFinishInit. If not, this step is left to the last invocation of the IntWinGuestSectionInMemory callback. Once IntWinGuestFinishInit is called the kernel buffer can be safely used.

Parameters
[in]KernelHeadersA buffer containing the MZPE headers of the kernel. This buffer should be at least PAGE_SIZE in size.
Return values
INT_STATUS_SUCCESSin case of success. Note that even if this function exits with a success status, the kernel buffer is not necessarily valid yet, as parts of it may be read in an asynchronous manner.
INT_STATUS_INVALID_OBJECT_TYPEif the MZPE validation of the headers fails
INT_STATUS_NOT_SUPPORTEDif a section header can not be parsed
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available
INT_STATUS_INVALID_INTERNAL_STATEif an internal error is encountered

Definition at line 1286 of file winguest.c.

Referenced by IntWinGuestKernelHeadersInMemory().

◆ IntWinGuestResolveImports()

static INTSTATUS IntWinGuestResolveImports ( void  )
static

Obtains the addresses of public variable and functions exposed by the Windows kernel.

On success, this will obtain the addresses of PsCreateSystemThread, ExAllocatePoolWithTag, ExFreePoolWithTag, NtBuildNumber, NtBuildLab, the value of the NtBuildNumber, and the contents of the NtBuildLab string. For 32-bit guests, it will also obtain the address of the KeServiceDescriptorTable and the number of services in the SSDT.

Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 840 of file winguest.c.

Referenced by IntWinGuestFinishInit().

◆ IntWinGuestSectionInMemory()

static INTSTATUS IntWinGuestSectionInMemory ( WIN_INIT_SWAP Context,
QWORD  Cr3,
QWORD  VirtualAddress,
QWORD  PhysicalAddress,
void *  Data,
DWORD  DataSize,
DWORD  Flags 
)
static

Handles the swap in of a kernel section done while the WINDOWS_GUEST.KernelBuffer is read.

This is the IntSwapMemRead handler set by IntWinGuestReadKernel that will read a kernel section into the kernel buffer. It will set the appropriate part of the WINDOWS_GUEST.KernelBuffer with the data obtained from the guest and will decrement the WINDOWS_GUEST.RemainingSections counter. It will also remove Context from the WINDOWS_GUEST.InitSwapHandles list and will free it.

Parameters
[in]ContextThe init swap handle used for this section
[in]Cr3Ignored
[in]VirtualAddressIgnored
[in]PhysicalAddressIgnored
[in]DataThe data read from the kernel
[in]DataSizeThe size of the Data buffer
[in]FlagsA combination of flags describing the way in which the data was read. This function checks only for the SWAPMEM_FLAG_ASYNC_CALL flag. If it is present, it means that it was invoked asynchronously, in which case it will pause the VCPUs in order to ensure consistency of the data. If the WINDOWS_GUEST.RemainingSections is set to 0 by this callback while SWAPMEM_FLAG_ASYNC_CALL is set, it will also finalize the initialization using IntWinGuestFinishInit since there are no more sections left to read. If all the sections are read synchronously, this action will be done by IntWinGuestReadKernel.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value

Definition at line 1197 of file winguest.c.

Referenced by IntWinGuestReadKernel().

◆ IntWinGuestUninit()

void IntWinGuestUninit ( void  )

Uninits a Windows guest.

This will run the uninit routines for all the Windows subsystems and will also free any resources held by the WINDOWS_GUEST state. After this function returns, the GuestInitialized field of gGuest will be set to False.

Definition at line 671 of file winguest.c.

Referenced by IntGuestUninit().

◆ IntWinGuestValidateKernel()

static INTSTATUS IntWinGuestValidateKernel ( QWORD  KernelBase,
QWORD  KernelGva,
BYTE KernelHeaders 
)
static

Validates if the presumed kernel base is the real kernel base, based on various checks.

The checks include verifying if the KernelGva from which the search has started is contained inside a non-writable, non-discardable and executable section. Another check is to verify if the current kernel base is found in the .data/ALMOSTRO section. Note that this should always be true, due to the presence of PsNtosImageBase variable in .data, which is used for various purposes inside the kernel, such as fetching a function address (through a MmGetSystemRoutineAddress call).

Parameters
[in]KernelBaseThe currently presumed kernel base.
[in]KernelGvaThe address from where the search for the kernel base has been started.
[in]KernelHeadersA mapping containing the first page of the presumed kernel base.
Return values
INT_STATUS_SUCCESSIf all the validations pass.
INT_STATUS_INVALID_DATA_STATEIf the KernelGva address is not in a non-writable, non-discardable and executable section, or the .data or ALMOSTRO sections do not exist.
INT_STATUS_ALIGNMENT_INCONSISTENCYIf the .data section is not page aligned.
INT_STATUS_NOT_FOUNDIf the PsNtosImageBase variable could not be found.
INT_STATUS_INVALID_DATA_SIZEIf any of the parsed sections has a size exceeding 2MB.
INT_STATUS_INSUFFICIENT_RESOURCESIf there are not enough resources for auxiliary allocations.

Definition at line 1770 of file winguest.c.

Referenced by IntWinGuestFindKernel().

Variable Documentation

◆ gWinGuest