82 .FieldName =
"CryptoExponent",
89 .FieldName =
"LargePageMinimum",
96 .FieldName =
"AppCompatFlag",
103 .FieldName =
"NtBuildNumber",
104 .FieldOffset = 0x260,
110 .FieldName =
"NtProductType",
111 .FieldOffset = 0x264,
117 .FieldName =
"ProductTypeIsValid",
118 .FieldOffset = 0x268,
124 .FieldName =
"NativeProcessorArchitecture",
125 .FieldOffset = 0x26a,
131 .FieldName =
"NtMajorVersion",
132 .FieldOffset = 0x26c,
138 .FieldName =
"NtMinorVersion",
139 .FieldOffset = 0x270,
145 .FieldName =
"ProcessorFeatures1",
146 .FieldOffset = 0x274,
152 .FieldName =
"ProcessorFeatures2",
153 .FieldOffset = 0x27c,
159 .FieldName =
"ProcessorFeatures3",
160 .FieldOffset = 0x284,
166 .FieldName =
"ProcessorFeatures4",
167 .FieldOffset = 0x28c,
173 .FieldName =
"ProcessorFeatures5",
174 .FieldOffset = 0x294,
180 .FieldName =
"ProcessorFeatures6",
181 .FieldOffset = 0x29c,
187 .FieldName =
"ProcessorFeatures7",
188 .FieldOffset = 0x2a4,
194 .FieldName =
"ProcessorFeatures8",
195 .FieldOffset = 0x2ac,
201 .FieldName =
"KdDebuggerEnabled",
202 .FieldOffset = 0x2d4,
208 .FieldName =
"MitigationPolicies",
209 .FieldOffset = 0x2d5,
215 .FieldName =
"SafeBootMode",
216 .FieldOffset = 0x2ec,
222 .FieldName =
"VirtualizationFlags",
223 .FieldOffset = 0x2ed,
229 .FieldName =
"TestRetInstruction",
230 .FieldOffset = 0x2f8,
236 .FieldName =
"SystemCall",
237 .FieldOffset = 0x308,
244 .FieldName =
"SystemCallPad1",
245 .FieldOffset = 0x310,
251 .FieldName =
"SystemCallPad2",
252 .FieldOffset = 0x318,
258 .FieldName =
"EnclaveFeatureMask1",
259 .FieldOffset = 0x36c,
265 .FieldName =
"EnclaveFeatureMask2",
266 .FieldOffset = 0x374,
272 .FieldName =
"ImageFileExecutionOptions",
273 .FieldOffset = 0x3a0,
279 .FieldName =
"ActiveProcessorCount",
280 .FieldOffset = 0x3c0,
288 .FieldName =
"AfterSudRegion",
289 .FieldOffset = 0x800,
291 .ShouldBeZero =
TRUE,
299 _In_ void *Originator,
359 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
394 exitAfterInformation =
TRUE;
398 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed: %08x\n", status);
400 exitAfterInformation =
TRUE;
411 ERROR(
"[ERROR] IntExceptGetVictimEpt failed: %08x\n", status);
413 exitAfterInformation =
TRUE;
416 if (exitAfterInformation)
429 LOG(
"[SUD-EXEC] An execution on shared user data occured in kernel-mode!\n");
471 ERROR(
"[ERROR] No process found with cr3: 0x%016llx, but ring is 3! Will inject #UD!",
481 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
482 exitAfterInformation =
TRUE;
493 ERROR(
"[ERROR] Failed getting modified zone: 0x%08x\n", status);
494 exitAfterInformation =
TRUE;
496 if (exitAfterInformation)
509 LOG(
"[SUD-EXEC] An execution on shared user data occured in user-mode!\n");
552 QWORD currentThread = 0;
562 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
573 ERROR(
"[ERROR] IntWinSudHandleKernelSudExec failed: 0x%08x\n", status);
581 ERROR(
"[ERROR] IntWinThrGetCurrentThread failed: 0x%08x\n", status);
588 goto cleanup_and_take_action;
594 ERROR(
"[ERROR] IntWinSudHandleKernelSudExec failed: 0x%08x\n", status);
598 cleanup_and_take_action:
608 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
626 ERROR(
"[ERROR] IntInjectExceptionInGuest failed: 0x%08x\n", status);
638 ERROR(
"[ERROR] IntUDAddToPendingList failed: 0x%08x\n", status);
673 if (NULL != gSudExecHook)
689 ERROR(
"[ERROR] IntHookGvaSetHook failed: 0x%08x\n", status);
709 if (NULL == gSudExecHook)
717 ERROR(
"[ERROR] IntHookGvaRemoveHook failed: 0x%08x\n", status);
742 switch (Field->FieldSize)
745 currentValue =
gSudBuffer[Field->FieldOffset];
760 *CurrentValue = currentValue;
787 memzero(pIntViol,
sizeof(*pIntViol));
813 pIntViol->
Size = Field->FieldSize;
822 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
871 victim.
WriteInfo.OldValue[0] = Field->OldValue;
873 if (Field->ShouldBeZero)
879 DWORD startOffset = Field->FieldOffset;
882 for (
DWORD i = Field->FieldOffset; i < (
DWORD)Field->FieldOffset + Field->FieldSize; i++)
891 copySize =
MIN(
sizeof(victim.
WriteInfo.NewValue), (
QWORD)Field->FieldOffset + Field->FieldSize - startOffset);
900 victim.
WriteInfo.AccessSize = Field->FieldSize;
915 if (Field->ShouldBeZero)
919 Field->ReenableOnZero =
TRUE;
924 Field->OldValue = NewValue;
929 if (Field->ShouldBeZero)
939 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
946 for (
DWORD i = Field->FieldOffset; i < (
DWORD)Field->FieldOffset + Field->FieldSize; i++)
967 ERROR(
"[ERROR] IntKernVirtMemWrite failed for gva 0x%016llx: 0x%08x\n",
1018 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1019 goto _cleanup_and_exit;
1062 if (gProtFields[i].
OldValue != newValue)
1064 WARNING(
"[WARNING] At field %s offset 0x%x, value should be 0x%llx but is 0x%llx\n",
1076 WARNING(
"[WARNING] IntWinSudHandleFieldModification failed: 0x%08x\n", status);
1086 WARNING(
"[WARNING] Field %s written more than the threshold, will disable!\n", gProtFields[i].
FieldName);
1130 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1131 goto _cleanup_and_exit;
1138 if (memcmp(gProtFields[i].
FieldName,
"AfterSudRegion",
sizeof(
"AfterSudRegion")) == 0)
1152 ERROR(
"[ERROR] Field %s is invalid, will disable!\n", gProtFields[i].FieldName);
1159 ERROR(
"[ERROR] Field %s with size %d is invalid, will disable!\n",
1160 gProtFields[i].FieldName, gProtFields[i].
FieldSize);
Measures kernel mode exceptions checks.
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
INTRO_CODEBLOCKS CodeBlocks
Code blocks extracted for the alert.
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
QWORD IntAlertCoreGetFlags(QWORD ProtectionFlag, INTRO_ACTION_REASON Reason)
Returns the flags for an alert.
An internal error occurred (no memory, pages not present, etc.).
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
struct _SHARED_USER_DATA_PROT_FIELD * PSHARED_USER_DATA_PROT_FIELD
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
QWORD ZoneFlags
The flags of the modified zone.
struct _SHARED_USER_DATA_PROT_FIELD SHARED_USER_DATA_PROT_FIELD
Describes a field from KUSER_SHARED_DATA which is protected through integrity.
IG_ARCH_REGS Regs
The current state of the guest registers.
DWORD Index
The VCPU number.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
BOOLEAN IntPolicyCoreTakeAction(QWORD Flag, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a core introspection option.
Measures user mode exceptions checks.
struct _EXCEPTION_UM_ORIGINATOR::@75 Return
QWORD ReturnRip
The RIP at which the code that triggered the alert returns.
void IntAlertFillWinProcess(const WIN_PROCESS_OBJECT *Process, INTRO_PROCESS *EventProcess)
Saves information about a windows process inside an alert.
Event structure for integrity violations on monitored structures.
#define INT_SUCCESS(Status)
INTSTATUS IntWinThrGetCurrentThread(DWORD CpuNumber, QWORD *EthreadAddress)
Get the ETHREAD structure address of the thread currently running on the given CPU.
char * FieldName
The name of the KUSER_SHARED_DATA field.
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
struct _EVENT_INTEGRITY_VIOLATION::@304 Victim
SHARED_USER_DATA_PROT_FIELD gProtFields[]
Global array containing the descriptors used for protecting fields inside SharedUserData.
INFO_UD_PENDING * IntUDGetEntry(const QWORD Cr3, const QWORD Rip, const QWORD Thread)
Get a UD entry for the provided Cr3, Rip and Thread ID.
Measures the checks done on SharedUserData.
#define INT_STATUS_NOT_NEEDED_HINT
Describes a user-mode originator.
#define ALERT_FLAG_ASYNC
If set, the alert was generated in an async manner.
struct _EVENT_EPT_VIOLATION::@283 Originator
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
INTSTATUS IntWinSudUnprotectIntegrity(void)
Uninitializes the SharedUserData integrity protection.
static BOOLEAN IntWinSudFetchFieldCurrentValue(SHARED_USER_DATA_PROT_FIELD *Field, QWORD *CurrentValue)
Fetches the value of the given described field from the global SharedUserData buffer.
#define INT_STATUS_NOT_FOUND
DWORD Offset
The offset of the modification.
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
#define INTRO_OPT_PROT_KM_SUD_INTEGRITY
Enable integrity checks over various SharedUserData fields, as well as the zero-filled zone after the...
Integrity protection of SharedUserData region.
Describes a kernel-mode originator.
INTSTATUS IntPhysicalMemWrite(QWORD PhysicalAddress, DWORD Length, void *Buffer)
Writes data to a guest physical memory range, but only for a single page.
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
INTSTATUS IntDumpCodeAndRegs(QWORD Gva, QWORD Gpa, IG_ARCH_REGS *Registers)
This function dumps an entire page (textual disassembly and opcodes) as well as the values of the reg...
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
Measures the execution handling on SharedUserData page.
INSTRUX Instruction
The current instruction, pointed by the guest RIP.
TIMER_FRIENDLY INTSTATUS IntWinSudCheckIntegrity(void)
This function checks the integrity of protected fields from SharedUserData, described in gProtFields...
struct _EXCEPTION_KM_ORIGINATOR::@63 Return
#define WIN_SHARED_USER_DATA_PTR
The address where the SharedUserData is mapped in the Windows kernel.
static INTSTATUS IntWinSudHandleSudExec(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Ept callback which handles executions inside SharedUserData.
BOOLEAN UtilIsBufferZero(void *Buffer, size_t BufferSize)
INTSTATUS IntHookGvaSetHook(QWORD Cr3, QWORD Gva, DWORD Length, BYTE Type, void *Callback, void *Context, void *ParentHook, DWORD Flags, HOOK_GVA **GvaHook)
Set a read, write, execute or swap hook on a guest virtual address.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
INTRO_VIOLATION_HEADER Header
The alert header.
#define ZONE_INTEGRITY
Used for integrity zone.
static HOOK_GVA * gSudExecHook
The hook object protecting against executions on SharedUserData.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
EXCEPTION_VICTIM_OBJECT Object
The modified object.
INTSTATUS IntAlertFillCodeBlocks(QWORD Rip, QWORD Cr3, BOOLEAN Execute, INTRO_CODEBLOCKS *CodeBlocks)
Fills the code blocks pattern for an alert.
Exposes the functions used to provide Windows Threads related support.
void * Library
The library that's modifying the memory (if that's the case).
BOOLEAN ShouldBeZero
Set to TRUE if the contents of the field should be always zero.
void IntAlertEptFillFromKmOriginator(const EXCEPTION_KM_ORIGINATOR *Originator, EVENT_EPT_VIOLATION *EptViolation)
Fills kernel mode originator information inside an EPT alert.
GENERIC_ALERT gAlert
Global alert buffer.
QWORD BaseAddress
Depending on INTRO_OBJECT_TYPE we have: CR3 for processes / ModuleBase for km drivers and um dll...
void IntAlertFillWriteInfo(const EXCEPTION_VICTIM_ZONE *Victim, INTRO_WRITE_INFO *WriteInfo)
Fills the write information for an alert.
static BOOLEAN gSudIntegrityInitialized
Is set to true when integrity is initialized on SharedUserData signaling that checks can be performed...
#define INITIAL_CRC_VALUE
#define INT_STATUS_EXCEPTION_BLOCK
DWORD Size
The size of the modified memory area.
#define INT_STATUS_ALREADY_INITIALIZED
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
#define INT_STATUS_NOT_INITIALIZED
The modified object is inside an integrity hook.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
__noreturn void IntBugCheck(void)
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
#define ZONE_EXECUTE
Used for execute violation.
INTSTATUS IntExceptGetVictimEpt(void *Context, QWORD Gpa, QWORD Gva, INTRO_OBJECT_TYPE Type, DWORD ZoneFlags, EXCEPTION_VICTIM_ZONE *Victim)
Fills an EXCEPTION_VICTIM_ZONE with relevant information from an EPT violation.
QWORD Current
The currently used options.
void IntExceptUserLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_UM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a user-mode violation, dumps the code-blocks and the injection buffer...
static BYTE * gSudBuffer
Buffer for fast accessing the current contents of SharedUserData.
QWORD VirtualAddress
The guest virtual address which was modified.
INTRO_VIOLATION_HEADER Header
The alert header.
INTSTATUS IntWinSudProtectSudExec(void)
Protects SharedUserData against executions by establishing an EPT hook on it.
QWORD StartVirtualAddress
The start address of the integrity zone.
#define HpFreeAndNullWithTag(Add, Tag)
INFO_UD_PENDING * CurrentUD
The currently pending #UD injection on this CPU.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3(QWORD Cr3)
Finds a process by its kernel CR3.
#define INT_STATUS_INVALID_INTERNAL_STATE
DWORD NameHash
The hash of the modified object.
INTSTATUS IntWinSudUnprotectSudExec(void)
Removes the execution EPT hook on SharedUserData.
void IntExceptKernelLogInformation(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Print the information about a kernel-mode violation and dumps the code-blocks.
INTRO_OBJECT_TYPE Type
The type of the modified object.
ZONE_TYPE ZoneType
The type of the modified zone.
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
WORD FieldSize
The size of the field. Note that this size can be 1, 2, 4, 8 for fields which are initialized...
INTSTATUS IntHookGvaRemoveHook(HOOK_GVA **Hook, DWORD Flags)
Remove a GVA hook.
Sent when an EPT violation triggers an alert. See EVENT_EPT_VIOLATION.
#define ALERT_FLAG_NOT_RING0
If set, the alert was triggered in ring 1, 2 or 3.
QWORD OldValue
The saved value for fields that don't have ShouldBeZero set to TRUE.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
struct _EXCEPTION_VICTIM_ZONE::@58::@60 WriteInfo
Executions inside the SharedUserData region.
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
WCHAR Name[ALERT_PATH_MAX_LEN]
NULL-terminated string with a human readable description of the modified object.
BOOLEAN ReenableOnZero
Set to TRUE after an allowed modification has been made on a field with ShouldBeZero set to TRUE...
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTRO_WRITE_INFO WriteInfo
__must_check INTSTATUS IntVirtMemMap(QWORD Gva, DWORD Length, QWORD Cr3, DWORD Flags, void **HostPtr)
Maps a guest virtual memory range inside Introcore virtual address space.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
GUEST_STATE gGuest
The current guest state.
void IntAlertFillWinProcessByCr3(QWORD ProcessCr3, INTRO_PROCESS *EventProcess)
Saves information about a Windows process inside an alert. The process is searched by its kernel CR3...
static INTSTATUS IntWinSudHandleUserSudExec(QWORD Address, INTRO_ACTION *Action)
Handles an user-mode execution inside SharedUserData.
EVENT_INTEGRITY_VIOLATION Integrity
QWORD Rsp
The value of the guest RSP register at the moment of execution.
struct _EXCEPTION_KM_ORIGINATOR::@64 Original
INTRO_ACTION Action
The action that was taken as the result of this alert.
char * Name
The modified process name.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
static void IntWinSudSendSudExecAlert(void *Originator, EXCEPTION_VICTIM_ZONE *Victim, BOOLEAN IsKernel, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Constructs and sends an EVENT_EPT_VIOLATION alert which occurred due to an execution in SharedUserDat...
INTSTATUS IntUDAddToPendingList(const QWORD Cr3, const QWORD Rip, const QWORD Thread, INFO_UD_PENDING **CurrentPendingUD)
Add a new UD to the list of pending injections.
static void IntWinSudSendSudIntegrityAlert(EXCEPTION_VICTIM_ZONE *Victim, SHARED_USER_DATA_PROT_FIELD *Field, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Completes and sends an alert for a detected SharedUserData modification on a monitored field...
QWORD BaseAddress
The guest virtual address at which the monitored integrity region starts.
INTSTATUS IntExceptUserGetExecOriginator(void *Process, EXCEPTION_UM_ORIGINATOR *Originator)
This function is used to get the originator for heap execution.
#define INT_STATUS_NOT_INITIALIZED_HINT
INTRO_PROCESS CurrentProcess
The current process.
#define INTRO_OPT_PROT_KM_SUD_EXEC
Enable protection against executions on SharedUserData.
VCPU_STATE * gVcpu
The state of the current VCPU.
The action was blocked because there was no exception for it.
void IntAlertFillWinUmModule(const WIN_PROCESS_MODULE *Module, INTRO_MODULE *EventModule)
Fills information about a user mode module inside an alert.
Sent for integrity violation alerts. See EVENT_INTEGRITY_VIOLATION.
DWORD Crc32String(const char *String, DWORD InitialCrc)
Computes the CRC for a NULL-terminated utf-8 string.
EXCEPTION_VICTIM_INTEGRITY Integrity
Valid if the modified zone is Integrity.
INTRO_EXEC_INFO ExecInfo
Execution information. Valid only if Violation is IG_EPT_HOOK_EXECUTE.
Event structure for EPT violations.
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
static INTSTATUS IntWinSudHandleFieldModification(SHARED_USER_DATA_PROT_FIELD *Field, QWORD NewValue)
This function is called when a modification has been detected on a given field in order to take a dec...
DWORD Length
The length of the instruction.
Exploitation of Remote Services.
DWORD ModifiedCount
The number of modifications on the field from the time the protection has been initialized up until n...
INTSTATUS IntExceptKernelGetOriginator(EXCEPTION_KM_ORIGINATOR *Originator, DWORD Options)
This function is used to get the information about the kernel-mode originator.
INTSTATUS IntAlertFillExecContext(QWORD Cr3, INTRO_EXEC_CONTEXT *ExecContext)
Fills the current execution context.
#define ZONE_WRITE
Used for write violation.
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
INTSTATUS IntWinSudProtectIntegrity(void)
Initializes the SharedUserData integrity protection.
WCHAR * utf8toutf16(WCHAR *Destination, const char *Source, DWORD DestinationMaxLength)
QWORD Rip
Where the write/exec came.
void IntExcept(EXCEPTION_VICTIM_ZONE *Victim, void *Originator, EXCEPTION_TYPE Type, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason, INTRO_EVENT_TYPE EventClass)
This function is the entry point for the exception mechanism.
Describes a field from KUSER_SHARED_DATA which is protected through integrity.
static INTSTATUS IntWinSudHandleKernelSudExec(QWORD Address, INTRO_ACTION *Action)
Handles a kernel mode execution inside SharedUserData.
INTRO_MODULE ReturnModule
The module to which the current code returns to.
DWORD NameHash
The namehash of the originator return driver.
This structure describes a running process inside the guest.
#define INT_STATUS_INSUFFICIENT_RESOURCES