Bitdefender Hypervisor Memory Introspection
Guest API detours

Guest functions hooked by introcore. More...

Files

file  detours.h
 The guest detour API.
 
file  winhkhnd.h
 Windows detour descriptors.
 
file  detours.c
 The guest detour API implementation.
 
file  winhkhnd.c
 Windows detour descriptors.
 

Functions

INTSTATUS IntDriverLoadHandler (void const *Detour)
 The detour handler that will be invoked when a guest loads a new driver.This handles driver loading in both Windows and Linux OSs. It simply gathers the arguments from the guest and delegates the driver loading event to IntLixDrvCreateFromAddress or IntWinDrvCreateFromAddress. If one of this function fails Introcore will try to trap to a debugger. More...
 
INTSTATUS IntDriverUnloadHandler (void const *Detour)
 The detour handler that will be invoked when a guest driver is unloaded.This handles driver unloading for both Windows and Linux OSs. It simply gathers the arguments from the guest and delegates the driver unloading event to IntLixDrvRemoveFromAddress or IntWinDrvRemoveFromAddress. If one of this function fails introcore will try to trap to a debugger. More...
 
INTSTATUS IntWinBcHandleBugCheck (void const *Detour)
 Handles a Windows OS crash.This is the detour handle for the KeBugCheck2 32-bit Windows kernel API and the KeBugCheckEx 64-bit Windows kernel API. This will log as much information as possible and will notify the integrator about the event. More...
 
INTSTATUS IntWinPoolHandleAlloc (void *Detour)
 Detour callback for ExAllocatePoolWithTag.Handles allocations within a Windows guest, executed using the ExAllocatePoolWithTag API. Basically, it will check the tag of the allocation, and if it identifies an allocation for a driver object or a fast I/O dispatch, it will patch the Size argument of the call so that it's almost a page. This ensures us that critical structures protected by the introspection will be allocated alone in each page, which gives us an enormous performance boost. More...
 
INTSTATUS IntWinPoolHandleFree (void *Detour)
 Detour callback for ExFreePoolWithTag.This function handles de-allocation requests executed by the guest. It will check the list of hooked structures to check if any of the structures is being de-allocated, in which case, it will remove the EPT protection on that structure. More...
 
INTSTATUS IntWinPowHandlePowerStateChange (void *Detour)
 Detour callback which is called whenever NtSetSystemPowerState is called, resulting in a hypercall to the introspection engine. More...
 
INTSTATUS IntWinVadHandleInsert (void const *Detour)
 The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertVad guest API. More...
 
INTSTATUS IntWinVadHandleInsertPrivate (void const *Detour)
 The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertPrivateVad guest API. More...
 
INTSTATUS IntWinPatchVadHandleCommit (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiCommitExistingVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the values of winKmFieldPcrCurrentThread, winKmFieldThreadAttachedProcess, winKmFieldThreadProcess, and winKmFieldProcessSpare. For 32-bit kernels it will also patch the stack location at which the VmProtection parameter is located. More...
 
INTSTATUS IntWinVadHandleCommit (void const *Detour)
 The detour handler that will be invoked when an existing VAD is committed by the guest.This is the detour handler for the MiCommitExistingVad guest API. Due to the way we ignore certain VADs, this can be invoked either when protection is changed for a known VAD, in which case we have to adjust our protection; or, when protection is changed for a previously unknown VAD in a way that makes it relevant for Introcore, in which case we treat as a newly created VAD. More...
 
INTSTATUS IntWinVadHandleInsertMap (void const *Detour)
 The detour handler that will be invoked when a VAD is inserted in the guest VAD tree.This is the detour handler for the MiGetWsAndInsertVad guest API. More...
 
INTSTATUS IntWinVadHandleDeleteVaRange (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiDeleteVirtualAddresses guest API. More...
 
INTSTATUS IntWinVadHandleFinishVadDeletion (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiFinishVadDeletion guest API. More...
 
INTSTATUS IntWinVadHandleVirtualProtect (void const *Detour)
 The detour handler that will be invoked when a memory range contained by a VAD has the protection rights changed.This is the detour handler for the MiProtectVirtualMemory guest API, which usually gets called as a result of a user-mode application calling an API like VirtualProtect. More...
 
INTSTATUS IntWinVadPatchInsertPrivate (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiInsertPrivateVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchInsertMap (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiGetWsAndInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchVirtualProtect (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiProtectVirtualMemory guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchDeleteVaRange (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiDeleteVirtualAddresses guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchFinishVadDeletion (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiFinishVadDeletion guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinVadPatchInsert (QWORD FunctionAddress, API_HOOK_HANDLER *Handler, void *Descriptor)
 This is the PFUNC_PreDetourCallback for the MiInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare. More...
 
INTSTATUS IntWinProcHandleCreate (void *Detour)
 Detour handler for the PspInsertProcess Windows kernel API.The actual process creation is handled by IntWinProcHandleCreateInternal. This function establishes the context of the creation and, if needed, blocks the process creation. More...
 
INTSTATUS IntWinProcHandleTerminate (void *Detour)
 This functions handles the termination of a Windows process.This function is invoked every time "MmCleanProcessAddressSpace" is called (a process is being terminated) and is responsible for removing the process from all the internal structures. More...
 
INTSTATUS IntWinProcPatchCopyMemoryDetour (QWORD FunctionAddress, void *Handler, void *Descriptor)
 This functions is responsible for patching the detour that handles the "MmCopyVirtualMemory".This function is invoked every time "MmCopyVirtualMemory" is called (a process is writing/reading another process) but before the actual handler IntWinProcHandleCopyMemory, its purpose being to modify the hook code (see winhkhnd.c). More...
 
INTSTATUS IntWinProcHandleCopyMemory (void *Detour)
 This functions is responsible handling process read/write operations.This function is invoked every time "MmCopyVirtualMemory" is called (a process is writing/reading another process), its purpose being to block malicious operations, such as a credential dump (reading from lsass.exe). More...
 
INTSTATUS IntWinProcSwapIn (void *Detour)
 Detour handler for the MmInSwapProcess Windows kernel API.The detour on MmInSwapProcess is set inside the function after/before the EPROCESS.OutSwapped bit is disabled. The guest virtual address of EPROCESS structure is stored in a register and is provided by 'IntDetGetArgument'. An example for an instruction that is detoured is 'lock and dword ptr [rbx+440h],0FFFFFF7Fh'; in this case the guest virtual address of the EPROCESS is stored in RBX register. More...
 
INTSTATUS IntWinProcSwapOut (void *Detour)
 Detour handler for the KiOutSwapProcess Windows kernel API.The detour on KiOutSwapProcess is set after the MiOutSwapProcess is called (e.g. 'xor r15b, r15b'). The guest virtual address of EPROCESS structure is stored in a register and is provided by 'IntDetGetArgument'. An example for that is detoured sequence is 'mov rcx, rbx / call nt!MmOutSwapProcess / xor r15b, r15b' ; in this case the guest virtual address of the EPROCESS is stored in RBX register. More...
 
INTSTATUS IntWinProcHandleInstrument (void *Detour)
 Handles an exit on NtSetInformationProcess calls where the InformationClass argument is 40 (instrumentation callback).The originator is considered to be the current process (by cr3). The victim is taken from the first argument of the API call, which is a handle to the target process. However, we receive an _EPROCESS address thanks to the hook handler. More...
 
INTSTATUS IntWinThrHandleThreadHijack (void *Detour)
 Handles a SetContextThread call - blocking thread hijacking.Thread hijacking (amongst others) is an approach to the process injection attack technique which allows an attacker to execute arbitrary code in the context of another process. An attacker would achieve this by opening a victim process, writing some malicious code to its memory, pausing a running thread and modifying the thread`s execution context so that it will run the malicious code after the thread`s execution is resumed. If PROC_OPT_PROT_SET_THREAD_CTX is set, this detour handler will block malicious SetContextThread calls and send an alert. More...
 
INTSTATUS IntWinThrHandleQueueApc (void *Detour)
 Handles a NtQueueApcThreadEx call - blocking process injections.Asynchronous Procedure Call (APC) injection involves attaching malicious code to the APC Queue of a process's thread. Queued APC functions are executed when the thread enters an alterable state. A variation of APC injection, dubbed "Early Bird injection", involves creating a suspended process in which malicious code can be written and executed before the process' entry point (and potentially subsequent anti-malware hooks) via an APC. AtomBombing is another variation that utilizes APCs to invoke malicious code previously written to the global atom table. https://attack.mitre.org/techniques/T1055/. More...
 
INTSTATUS IntWinThrPatchThreadHijackHandler (QWORD FunctionAddress, void *Handler, void *Descriptor)
 This functions is responsible for patching the detour that handles the "PspSetContextThreadInternal".This function is called before the hook is placed into memory in order to "patch" the addresses of guest functions or guest file offsets that are used by the hook handler. Specifically, this patches the offsets of the AttachedProcess and Process fields of _KTHREAD and the Spare field of _KPROCESS, but also patches the "retn" instruction accordingly. More...
 
INTSTATUS IntWinThrPrepareApcHandler (QWORD FunctionAddress, void *Handler, void *Descriptor)
 This functions is responsible for patching the detour that handles the "NtQueueApcThreadEx".This function is called before the hook is placed into memory in order to "patch" the addresses of guest functions or guest file offsets that are used by the hook handler. Specifically, this patches the addresses of PsThreadType, ObReferenceObjectByHandle, ObDereferenceObject and the offsets of the AttachedProcess and Process fields of _KTHREAD and the Spare field of _KPROCESS, but also patches the "retn" instruction accordingly. More...
 
INTSTATUS IntWinHandleException (void *Detour)
 Handles a hardware exception triggered inside the guestThis is the detour handler for the guest KiDispatchException function: More...
 
INTSTATUS IntGuestUninitOnBugcheck (void const *Detour)
 Prepares Introcore unload in case of a guest crash in order to clean up the code and data injected inside the guestIf the INTRO_OPT_BUGCHECK_CLEANUP activation flag is not set, this function does nothing. Will set BugCheckInProgress inside gGuest to True. More...
 

Detailed Description

Guest functions hooked by introcore.

In order to intercept certain guest operations, VMEXIT events may not be enough. For example, if we want to know when a new process is inserted inside the guest process list. For these cases, introcore is able to hook guest functions. This is done in a pretty standard way: the first few instructions in a hooked function are replaced with a jump to a memory zone that contains code controlled by us (the in-guest detour handler). The in-guest handler can notify introcore about the event by issuing a hypercall. The in-guest handler can also do pre-processing on the event or can change the behavior of the guest without notifying introcore about it.

Function Documentation

◆ IntDriverLoadHandler()

INTSTATUS IntDriverLoadHandler ( void const *  Detour)

The detour handler that will be invoked when a guest loads a new driver.This handles driver loading in both Windows and Linux OSs. It simply gathers the arguments from the guest and delegates the driver loading event to IntLixDrvCreateFromAddress or IntWinDrvCreateFromAddress. If one of this function fails Introcore will try to trap to a debugger.

Parameters
[in]DetourThe detour handle. Ignored.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 45 of file drivers.c.

◆ IntDriverUnloadHandler()

INTSTATUS IntDriverUnloadHandler ( void const *  Detour)

The detour handler that will be invoked when a guest driver is unloaded.This handles driver unloading for both Windows and Linux OSs. It simply gathers the arguments from the guest and delegates the driver unloading event to IntLixDrvRemoveFromAddress or IntWinDrvRemoveFromAddress. If one of this function fails introcore will try to trap to a debugger.

Parameters
[in]DetourThe detour handle. Ignored.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 110 of file drivers.c.

◆ IntGuestUninitOnBugcheck()

INTSTATUS IntGuestUninitOnBugcheck ( void const *  Detour)

Prepares Introcore unload in case of a guest crash in order to clean up the code and data injected inside the guestIf the INTRO_OPT_BUGCHECK_CLEANUP activation flag is not set, this function does nothing. Will set BugCheckInProgress inside gGuest to True.

Parameters
[in]DetourIgnored
Return values
INT_STATUS_NOT_NEEDED_HINTif the INTRO_OPT_BUGCHECK_CLEANUP option is not active
INT_STATUS_REMOVE_DETOUR_AND_SET_RIPif cleanup should be done. This will make the detour mechanism remove the hook that invoked this handler in order to clean up the hook itself.

Definition at line 2522 of file introcore.c.

Referenced by IntLixCrashPanicHandler().

◆ IntWinBcHandleBugCheck()

INTSTATUS IntWinBcHandleBugCheck ( void const *  Detour)

Handles a Windows OS crash.This is the detour handle for the KeBugCheck2 32-bit Windows kernel API and the KeBugCheckEx 64-bit Windows kernel API. This will log as much information as possible and will notify the integrator about the event.

Parameters
[in]DetourThe detour handle for this hook.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Detour is NULL.

Definition at line 932 of file winbugcheck.c.

◆ IntWinHandleException()

INTSTATUS IntWinHandleException ( void *  Detour)

Handles a hardware exception triggered inside the guestThis is the detour handler for the guest KiDispatchException function:

void
KiDispatchException(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_opt_ PKEXCEPTION_FRAME ExceptionFrame,
_In_ PKTRAP_FRAME TrapFrame,
_In_ KPROCESSOR_MODE PreviousMode,
_In_ BOOLEAN FirstChance
);

This should catch any exception that originated in user mode. On windows 10, if a process has crashed it will have the Crashed bit set inside _EPROCESSS.Flags3 If __fastfail() was used, the error code will be the NTSTATUS value associated with the fast fail code used, and the Crashed bit will be set. See https://docs.microsoft.com/en-us/cpp/intrinsics/fastfail Some error codes are NTSTATUS values, some will be converted to a NTSTATUS value before execution is handed back to the guest. Some exceptions generated by higher-level languages will end up in KiDispatchException, but the Crashed bit will not be set. If the exception was generated by a DEP violation, an alert may be sent. See IntWinCrashHandleDepViolation. Exceptions that originated inside the kernel (PreviousMode is KERNEL_MODE) are ignored. The divide error generated by patch guard when Windows boots is also ignored.

Parameters
[in]DetourThe detour handle

Definition at line 544 of file winumcrash.c.

◆ IntWinPatchVadHandleCommit()

INTSTATUS IntWinPatchVadHandleCommit ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiCommitExistingVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the values of winKmFieldPcrCurrentThread, winKmFieldThreadAttachedProcess, winKmFieldThreadProcess, and winKmFieldProcessSpare. For 32-bit kernels it will also patch the stack location at which the VmProtection parameter is located.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 2960 of file winvad.c.

◆ IntWinPoolHandleAlloc()

INTSTATUS IntWinPoolHandleAlloc ( void *  Detour)

Detour callback for ExAllocatePoolWithTag.Handles allocations within a Windows guest, executed using the ExAllocatePoolWithTag API. Basically, it will check the tag of the allocation, and if it identifies an allocation for a driver object or a fast I/O dispatch, it will patch the Size argument of the call so that it's almost a page. This ensures us that critical structures protected by the introspection will be allocated alone in each page, which gives us an enormous performance boost.

Parameters
[in]DetourThe detour object.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 13 of file winpool.c.

◆ IntWinPoolHandleFree()

INTSTATUS IntWinPoolHandleFree ( void *  Detour)

Detour callback for ExFreePoolWithTag.This function handles de-allocation requests executed by the guest. It will check the list of hooked structures to check if any of the structures is being de-allocated, in which case, it will remove the EPT protection on that structure.

Parameters
[in]DetourThe detour object.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 106 of file winpool.c.

◆ IntWinPowHandlePowerStateChange()

INTSTATUS IntWinPowHandlePowerStateChange ( void *  Detour)

Detour callback which is called whenever NtSetSystemPowerState is called, resulting in a hypercall to the introspection engine.

Parameters
[in]DetourThe detour object.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_NOT_FOUNDIf an unknown power state change occurs.

Definition at line 273 of file winpower.c.

◆ IntWinProcHandleCopyMemory()

INTSTATUS IntWinProcHandleCopyMemory ( void *  Detour)

This functions is responsible handling process read/write operations.This function is invoked every time "MmCopyVirtualMemory" is called (a process is writing/reading another process), its purpose being to block malicious operations, such as a credential dump (reading from lsass.exe).

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSOn success.

BitDefender quick scan does this, but we will allow every agent (since they're injected by us).

Definition at line 2870 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcHandleCreate()

INTSTATUS IntWinProcHandleCreate ( void *  Detour)

Detour handler for the PspInsertProcess Windows kernel API.The actual process creation is handled by IntWinProcHandleCreateInternal. This function establishes the context of the creation and, if needed, blocks the process creation.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSAlways.

Definition at line 2610 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcHandleInstrument()

INTSTATUS IntWinProcHandleInstrument ( void *  Detour)

Handles an exit on NtSetInformationProcess calls where the InformationClass argument is 40 (instrumentation callback).The originator is considered to be the current process (by cr3). The victim is taken from the first argument of the API call, which is a handle to the target process. However, we receive an _EPROCESS address thanks to the hook handler.

Since this is an injection technique, we consider the address of the desired callback to be the address of the injected buffer and, since we don't have a size for it, the buffer is always considerd to have a PAGE_SIZE size.

This will check wether or not the instrumentation attempt is valid or not via exceptions and take propper action. If the attempt is deemed malicious, we will set the guest to return from the function with a STATUS_ACCESS_DENIED or to continue normal execution otherwise.

Parameters
[in]DetourThe detour.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 4433 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcHandleTerminate()

INTSTATUS IntWinProcHandleTerminate ( void *  Detour)

This functions handles the termination of a Windows process.This function is invoked every time "MmCleanProcessAddressSpace" is called (a process is being terminated) and is responsible for removing the process from all the internal structures.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 2682 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcPatchCopyMemoryDetour()

INTSTATUS IntWinProcPatchCopyMemoryDetour ( QWORD  FunctionAddress,
void *  Handler,
void *  Descriptor 
)

This functions is responsible for patching the detour that handles the "MmCopyVirtualMemory".This function is invoked every time "MmCopyVirtualMemory" is called (a process is writing/reading another process) but before the actual handler IntWinProcHandleCopyMemory, its purpose being to modify the hook code (see winhkhnd.c).

Parameters
[in]FunctionAddressThe address of the function.
[in]HandlerAn API_HOOK_HANDLER structure.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 2746 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcSwapIn()

INTSTATUS IntWinProcSwapIn ( void *  Detour)

Detour handler for the MmInSwapProcess Windows kernel API.The detour on MmInSwapProcess is set inside the function after/before the EPROCESS.OutSwapped bit is disabled. The guest virtual address of EPROCESS structure is stored in a register and is provided by 'IntDetGetArgument'. An example for an instruction that is detoured is 'lock and dword ptr [rbx+440h],0FFFFFF7Fh'; in this case the guest virtual address of the EPROCESS is stored in RBX register.

When the process is swapped-in, the WIN_PROCESS_OBJECT is destroyed and a new one is created because some information about EPROCESS may change.

At this point, the process is swapped-in and the protection is activated.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INVALID_DATA_TYPEIf the callback is called and the process was not swapped-out.

Definition at line 4214 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinProcSwapOut()

INTSTATUS IntWinProcSwapOut ( void *  Detour)

Detour handler for the KiOutSwapProcess Windows kernel API.The detour on KiOutSwapProcess is set after the MiOutSwapProcess is called (e.g. 'xor r15b, r15b'). The guest virtual address of EPROCESS structure is stored in a register and is provided by 'IntDetGetArgument'. An example for that is detoured sequence is 'mov rcx, rbx / call nt!MmOutSwapProcess / xor r15b, r15b' ; in this case the guest virtual address of the EPROCESS is stored in RBX register.

When the process is swapped-out, the WIN_PROCESS_OBJECT is marked as swapped-out. The protection for this process is deactivated and all swap-mem transactions are removed.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSAlways.

Definition at line 4318 of file winprocess.c.

Referenced by IntWinProcPolicyIsFeedback().

◆ IntWinThrHandleQueueApc()

INTSTATUS IntWinThrHandleQueueApc ( void *  Detour)

Handles a NtQueueApcThreadEx call - blocking process injections.Asynchronous Procedure Call (APC) injection involves attaching malicious code to the APC Queue of a process's thread. Queued APC functions are executed when the thread enters an alterable state. A variation of APC injection, dubbed "Early Bird injection", involves creating a suspended process in which malicious code can be written and executed before the process' entry point (and potentially subsequent anti-malware hooks) via an APC. AtomBombing is another variation that utilizes APCs to invoke malicious code previously written to the global atom table. https://attack.mitre.org/techniques/T1055/.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 758 of file winthread.c.

◆ IntWinThrHandleThreadHijack()

INTSTATUS IntWinThrHandleThreadHijack ( void *  Detour)

Handles a SetContextThread call - blocking thread hijacking.Thread hijacking (amongst others) is an approach to the process injection attack technique which allows an attacker to execute arbitrary code in the context of another process. An attacker would achieve this by opening a victim process, writing some malicious code to its memory, pausing a running thread and modifying the thread`s execution context so that it will run the malicious code after the thread`s execution is resumed. If PROC_OPT_PROT_SET_THREAD_CTX is set, this detour handler will block malicious SetContextThread calls and send an alert.

Parameters
[in]DetourThe detour.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 429 of file winthread.c.

◆ IntWinThrPatchThreadHijackHandler()

INTSTATUS IntWinThrPatchThreadHijackHandler ( QWORD  FunctionAddress,
void *  Handler,
void *  Descriptor 
)

This functions is responsible for patching the detour that handles the "PspSetContextThreadInternal".This function is called before the hook is placed into memory in order to "patch" the addresses of guest functions or guest file offsets that are used by the hook handler. Specifically, this patches the offsets of the AttachedProcess and Process fields of _KTHREAD and the Spare field of _KPROCESS, but also patches the "retn" instruction accordingly.

Parameters
[in]FunctionAddressThe address of the function.
[in]HandlerAn API_HOOK_HANDLER structure.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Return values
INT_STATUS_SUCCESSAlways.

Definition at line 1036 of file winthread.c.

◆ IntWinThrPrepareApcHandler()

INTSTATUS IntWinThrPrepareApcHandler ( QWORD  FunctionAddress,
void *  Handler,
void *  Descriptor 
)

This functions is responsible for patching the detour that handles the "NtQueueApcThreadEx".This function is called before the hook is placed into memory in order to "patch" the addresses of guest functions or guest file offsets that are used by the hook handler. Specifically, this patches the addresses of PsThreadType, ObReferenceObjectByHandle, ObDereferenceObject and the offsets of the AttachedProcess and Process fields of _KTHREAD and the Spare field of _KPROCESS, but also patches the "retn" instruction accordingly.

Parameters
[in]FunctionAddressThe address of the function.
[in]HandlerAn API_HOOK_HANDLER structure.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Return values
INT_STATUS_SUCCESSOn success.

Definition at line 1108 of file winthread.c.

◆ IntWinVadHandleCommit()

INTSTATUS IntWinVadHandleCommit ( void const *  Detour)

The detour handler that will be invoked when an existing VAD is committed by the guest.This is the detour handler for the MiCommitExistingVad guest API. Due to the way we ignore certain VADs, this can be invoked either when protection is changed for a known VAD, in which case we have to adjust our protection; or, when protection is changed for a previously unknown VAD in a way that makes it relevant for Introcore, in which case we treat as a newly created VAD.

This function will obtain 4 parameters from the guest: the guest virtual address of the _MMVAD structure, that first page of the modified memory range, the size of the modified memory range, and the protection applied for the given memory range. This means that for the VAD at the found GVA, the pages in the range [start, start + length - 1] have their protection policy modified. These changes are always done for the current process.

First, we obtain the current process, searching it by the currently loaded CR3. If the process is not protected, or if VADs are not monitored for it, we bail out.

Then, we try to find a matching VAD in our tree by the start of the modified memory range. If a VAD is found, it can be an old VAD that we haven't removed yet - this can be checked by comparing the guest virtual address of the _MMVAD structure with the known address in VAD.VadGva. If they match, we simply compute the start and end of the range, and delegate the changes to IntWinVadHandleProtectGeneric. If they don't match, we first try to insert the VAD now using IntWinVadHandleInsertGeneric (this will remove any old overlapping VADs). If no VAD is found, it means that we ignored it up until this point, so we insert it now into our tree using IntWinVadHandleInsertGeneric, then we handle the protection changes with IntWinVadHandleProtectGeneric. This two-step method is needed because the insert function will look only at the memory protection rights in the _MMVAD structure, which will be the original protection rights, not the newly set rights for the given range.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 3026 of file winvad.c.

◆ IntWinVadHandleDeleteVaRange()

INTSTATUS IntWinVadHandleDeleteVaRange ( void const *  Detour)

The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiDeleteVirtualAddresses guest API.

The process that owns the VAD is always the current process, which is obtained by using the currently loaded CR3.

This function obtains the start and end of the deleted range and passes the information to IntWinVadHandleDeleteGeneric. The deleted range is always inclusive and is always contained in a single VAD and it is either the entire VAD, or a sub-range of it.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 3197 of file winvad.c.

◆ IntWinVadHandleFinishVadDeletion()

INTSTATUS IntWinVadHandleFinishVadDeletion ( void const *  Detour)

The detour handler that will be invoked when a memory range contained by a VAD is deleted.This is the detour handler for the MiFinishVadDeletion guest API.

The process that owns the VAD is always the current process, which is obtained by using the currently loaded CR3.

This function obtains the start and end of the deleted range and passes the information to IntWinVadHandleDeleteGeneric. The deleted range is always inclusive and is always contained in a single VAD and it is either the entire VAD, or a sub-range of it.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 3268 of file winvad.c.

◆ IntWinVadHandleInsert()

INTSTATUS IntWinVadHandleInsert ( void const *  Detour)

The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertVad guest API.

It will gather from the guest two pieces of information: the guest virtual address of the _MMVAD structure, and the guest virtual address of the _EPROCESS that owns it. If the process for which the insertion is done is known by Introcore and if VAD monitoring is enabled for it, IntWinVadHandleInsertGeneric will handle the insertion. Since this could be invoked before the process is inserted in our list of processes, any VADs inserted for an unknown process will be ignored. Those will be detected later by a static memory scan done with IntWinVadImportProcessTree.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 2825 of file winvad.c.

◆ IntWinVadHandleInsertMap()

INTSTATUS IntWinVadHandleInsertMap ( void const *  Detour)

The detour handler that will be invoked when a VAD is inserted in the guest VAD tree.This is the detour handler for the MiGetWsAndInsertVad guest API.

The process that owns the VAD is always the current process, which is obtained by using the currently loaded CR3.

This function obtains the guest virtual address of the _MMVAD structure and delegates the insertion to IntWinVadHandleInsertGeneric.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 3142 of file winvad.c.

◆ IntWinVadHandleInsertPrivate()

INTSTATUS IntWinVadHandleInsertPrivate ( void const *  Detour)

The detour handler that will be invoked when the guest inserts a new VAD in the tree.This is the detour handler for the MiInsertPrivateVad guest API.

It will obtain the guest virtual address of the new _MMVAD structure and will delegate the insertion handling to IntWinVadHandleInsertGeneric. The process that owns the VAD is always the current process, which is obtained by searching it by the currently loaded CR3. Since this could be invoked before the process is inserted in our list of processes, any VADs inserted for an unknown process will be ignored. Those will be detected later by a static memory scan done with IntWinVadImportProcessTree.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 2897 of file winvad.c.

◆ IntWinVadHandleVirtualProtect()

INTSTATUS IntWinVadHandleVirtualProtect ( void const *  Detour)

The detour handler that will be invoked when a memory range contained by a VAD has the protection rights changed.This is the detour handler for the MiProtectVirtualMemory guest API, which usually gets called as a result of a user-mode application calling an API like VirtualProtect.

Since a process can change the protection rights for memory ranges inside other processes, the first thing this function does is to obtain the destination _EPROCESS guest virtual address. If that process is not protected, it bails out.

Then, it will obtain the guest virtual addresses at which the start and the length of the modified range are stored, as well as the new protection rights, which will be represented by one of the Windows memory protection constants (see https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants). The range for which the new rights are applied will always be contained inside a single VAD and will be inclusive. IntWinVadHandleProtectGeneric will take care of the actual changes.

Note that even if the length of the range is less than a 4K page, the rights for the entire page are changed, so the upper limit of the range is always the last modified page.

Parameters
[in]DetourThe detour for which this callback is invoked.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value.

Definition at line 3339 of file winvad.c.

◆ IntWinVadPatchDeleteVaRange()

INTSTATUS IntWinVadPatchDeleteVaRange ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiDeleteVirtualAddresses guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3678 of file winvad.c.

◆ IntWinVadPatchFinishVadDeletion()

INTSTATUS IntWinVadPatchFinishVadDeletion ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiFinishVadDeletion guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3726 of file winvad.c.

◆ IntWinVadPatchInsert()

INTSTATUS IntWinVadPatchInsert ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3770 of file winvad.c.

◆ IntWinVadPatchInsertMap()

INTSTATUS IntWinVadPatchInsertMap ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiGetWsAndInsertVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3572 of file winvad.c.

◆ IntWinVadPatchInsertPrivate()

INTSTATUS IntWinVadPatchInsertPrivate ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiInsertPrivateVad guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3512 of file winvad.c.

◆ IntWinVadPatchVirtualProtect()

INTSTATUS IntWinVadPatchVirtualProtect ( QWORD  FunctionAddress,
API_HOOK_HANDLER Handler,
void *  Descriptor 
)

This is the PFUNC_PreDetourCallback for the MiProtectVirtualMemory guest API detour.It will be invoked before the detour is placed inside the guest and will patch the detour handler with the value of winKmFieldProcessSpare.

Parameters
[in]FunctionAddressGuest virtual address of the hooked function. Ignored.
[in,out]HandlerThe hook handler structure. This will have the API_HOOK_HANDLER.Code byte array changed.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Returns
INT_STATUS_SUCCESS is always returned.

Definition at line 3621 of file winvad.c.