35 #define INTERRUPT_OBJECT_COUNT 0x20 40 #define DISPATCH_OFFSET (gGuest.Guest64 ? FIELD_OFFSET(KINTERRUPT_COMMON64, DispatchAddress) : \ 41 FIELD_OFFSET(KINTERRUPT_COMMON32, DispatchAddress)) 42 #define SERVICE_OFFSET (gGuest.Guest64 ? FIELD_OFFSET(KINTERRUPT_COMMON64, ServiceRoutine) : \ 46 FIELD_OFFSET(KINTERRUPT_COMMON32, ServiceRoutine)) 98 memzero(pEvent,
sizeof(*pEvent));
129 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
160 QWORD oldDispatchValue, oldServiceValue;
161 QWORD newDispatchValue = 0, newServiceValue = 0;
175 if (NULL == dispatchReg)
177 oldDispatchValue = 0;
184 if (NULL == serviceReg)
190 oldServiceValue = *(
QWORD *)serviceReg->OriginalContent;
196 ERROR(
"[ERROR] IntKernVirtMemFetchWordSize failed: 0x%08x\n", status);
203 ERROR(
"[ERROR] IntKernVirtMemFetchWordSize failed: 0x%08x\n", status);
207 if (newDispatchValue == oldDispatchValue && newServiceValue == oldServiceValue)
218 if (newDispatchValue == oldDispatchValue && serviceReg != NULL)
222 else if(dispatchReg != NULL)
240 ERROR(
"[ERROR] Failed getting integrity zone: 0x%08x\n", status);
245 victim.
WriteInfo.OldValue[0] = oldDispatchValue;
246 victim.
WriteInfo.OldValue[1] = oldServiceValue;
248 victim.
WriteInfo.NewValue[0] = newDispatchValue;
249 victim.
WriteInfo.NewValue[1] = newServiceValue;
257 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
299 ERROR(
"[ERROR] IntWinIntObjHandleModification failed: 0x%08x\n", status);
312 IntegrityRegion->Gva,
314 IntegrityRegion->OriginalContent,
321 ERROR(
"[ERROR] IntVirtMemSafeWrite failed for gva 0x%016llx: 0x%08x\n",
322 IntegrityRegion->Gva, status);
351 QWORD *oldArray = (
QWORD *)IntegrityRegion->OriginalContent;
359 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
365 if (oldArray[i] == newArray[i])
373 ERROR(
"[ERROR] IntWinIntObjHandleModification failed: 0x%08x\n", status);
374 goto cleanup_and_exit;
387 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08x\n", status);
388 goto cleanup_and_exit;
405 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%08x\n", status);
406 goto cleanup_and_exit;
416 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08x\n", status);
417 goto cleanup_and_exit;
434 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%08x\n", status);
435 goto cleanup_and_exit;
453 ERROR(
"[ERROR] IntVirtMemSafeWrite failed for gva 0x%016llx: 0x%08x\n",
455 goto cleanup_and_exit;
507 if (NULL == gDescriptors)
519 ERROR(
"[ERROR] IntFindKernelPcr failed: 0x%08x\n", status);
528 ERROR(
"[ERROR] IntKernVirtMemFetchWordSize failed: 0x%08x\n", status);
543 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%08x\n", status);
544 goto cleanup_and_exit;
551 QWORD currentIntObj = 0;
559 ERROR(
"[ERROR] IntKernVirtMemFetchWordSize failed: 0x%08x\n", status);
577 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%08x\n", status);
578 goto cleanup_and_exit;
590 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%08x\n", status);
591 goto cleanup_and_exit;
625 if (NULL == gDescriptors)
632 if (NULL == gDescriptors[i].ObjectIntegrityObject)
640 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08x\n", status);
650 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08x\n", status);
661 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08x\n", status);
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
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.
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
QWORD ZoneFlags
The flags of the modified zone.
void * ObjectIntegrityObject
The integrity object associated with the monitorized array.
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.
An interrupt object from KPRCB.
Event structure for integrity violations on monitored structures.
INTSTATUS IntIntegrityAddRegion(QWORD VirtualAddress, DWORD Length, INTRO_OBJECT_TYPE Type, void *Context, PFUNC_IntegrityViolationCallback Callback, BOOLEAN CopyContent, void **Descriptor)
Creates an INTEGRITY_REGION object and adds it to the gIntegrityRegions list.
#define INT_SUCCESS(Status)
#define DISPATCH_OFFSET
Helper macro for computing the offset of DispatchAddress inside the nt!_KINTERRUPT structure...
QWORD ObjectGva
The GVA of the current interrupt object.
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
struct _INTOBJ_PERPROC_DESCRIPTOR INTOBJ_PERPROC_DESCRIPTOR
Structure describing the protected InterruptObject array for a KPRCB associated with a CPU...
#define INT_STATUS_NOT_NEEDED_HINT
#define ALERT_FLAG_ASYNC
If set, the alert was generated in an async manner.
#define HpAllocWithTag(Len, Tag)
INTSTATUS IntKernVirtMemFetchWordSize(QWORD GuestVirtualAddress, void *Data)
Reads a guest pointer from the guest kernel memory.
int INTSTATUS
The status data type.
void * ServiceIntegrityObject
The integrity object associated with ServiceRoutine.
Describes a kernel-mode originator.
PVCPU_STATE VcpuArray
Array of the VCPUs assigned to this guest. The index in this array matches the VCPU number...
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
BYTE IdtEntry
The modified IDT entry. Valid only if Type is introObjectTypeIdt.
static INTSTATUS IntWinIntObjHandleObjectModification(INTEGRITY_REGION *IntegrityRegion)
Integrity callback for modifications detected inside protected objects.
#define VICTIM_INTERRUPT_OBJECT
Printable name used for introObjectTypeInterruptObject.
struct _INTOBJ_PERPROC_DESCRIPTOR * PINTOBJ_PERPROC_DESCRIPTOR
struct _INTOBJ_PROT_DESCRIPTOR INTOBJ_PROT_DESCRIPTOR
Structure describing a protected interrupt object.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
#define ZONE_INTEGRITY
Used for integrity zone.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
EXCEPTION_VICTIM_OBJECT Object
The modified object.
GENERIC_ALERT gAlert
Global alert buffer.
INTSTATUS IntIntegrityRecalculate(INTEGRITY_REGION *IntegrityRegion)
Recalculates the hash and reads the original content again for a given region.
void * DispatchIntegrityObject
The integrity object associated with DispatchAddress.
INTOBJ_PROT_DESCRIPTOR IntObjDescriptors[INTERRUPT_OBJECT_COUNT]
Array containing protection descriptors for each protected interrupt object in the array...
void IntAlertFillWriteInfo(const EXCEPTION_VICTIM_ZONE *Victim, INTRO_WRITE_INFO *WriteInfo)
Fills the write information for an alert.
INTSTATUS IntFindKernelPcr(DWORD CpuNumber, QWORD *Pcr)
Finds the address of the Windows kernel _KPCR.
DWORD Size
The size of the modified memory area.
#define INT_STATUS_NOT_INITIALIZED
Structure describing the protected InterruptObject array for a KPRCB associated with a CPU...
The modified object is inside an integrity hook.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
INTSTATUS IntWinIntObjProtect(void)
Protects the interrupt objects which are present in the KPRCB's InterruptObject array.
INTRO_MODULE Module
The module that modified the monitored region.
#define INTRO_OPT_PROT_KM_INTERRUPT_OBJ
Enable protection against modifications of interrupt objects from KPRCB's InterruptObject.
QWORD VirtualAddress
The guest virtual address which was modified.
INTRO_VIOLATION_HEADER Header
The alert header.
#define IS_KERNEL_POINTER_WIN(is64, p)
Checks if a guest virtual address resides inside the Windows kernel address space.
QWORD StartVirtualAddress
The start address of the integrity zone.
INTSTATUS IntExceptGetVictimIntegrity(INTEGRITY_REGION *IntegrityRegion, DWORD *Offset, EXCEPTION_VICTIM_ZONE *Victim)
This function is used to get the information about the modified zone from the integrity region...
#define HpFreeAndNullWithTag(Add, Tag)
static INTSTATUS IntWinIntObjHandleArrayModification(INTEGRITY_REGION *IntegrityRegion)
Integrity callback for modifications detected inside the array containing the protected objects...
#define INTERRUPT_OBJECT_COUNT
The number of protected interrupt objects.
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
INTRO_OBJECT_TYPE Type
The type of the modified object.
ZONE_TYPE ZoneType
The type of the modified zone.
static INTSTATUS IntWinIntObjSendIntegrityAlert(INTOBJ_PROT_DESCRIPTOR *Descriptor, EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Sends an introEventIntegrityViolation alert for a modified Interrupt Object entry.
#define SERVICE_OFFSET
Helper macro for computing the offset of ServiceRoutine inside the nt!_KINTERRUPT structure...
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
Describes the modified zone.
struct _INTOBJ_PROT_DESCRIPTOR * PINTOBJ_PROT_DESCRIPTOR
struct _EXCEPTION_VICTIM_ZONE::@58::@60 WriteInfo
#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 Valid
Set to True if the information in the structure is valid, False otherwise.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTSTATUS IntIntegrityRemoveRegion(void *Descriptor)
Removes an integrity region from the gIntegrityRegions list.
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.
BYTE InterruptObjIndex
The index of the modified interrupt object. Valid only for introObjectTypeInterruptObject.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
Structure describing a protected interrupt object.
GUEST_STATE gGuest
The current guest state.
void * OriginalContent
A buffer containing the original bytes of the associated region.
BYTE EntryIndex
The index of the current object in the InterruptObject array.
EVENT_INTEGRITY_VIOLATION Integrity
struct _EVENT_INTEGRITY_VIOLATION::@302 Originator
INTRO_ACTION Action
The action that was taken as the result of this alert.
QWORD BaseAddress
The guest virtual address at which the monitored integrity region starts.
INTSTATUS IntExceptGetOriginatorFromModification(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator)
This function is used for integrity violations to get the information about the kernel-mode originato...
INTRO_PROCESS CurrentProcess
The current process.
Sent for integrity violation alerts. See EVENT_INTEGRITY_VIOLATION.
EXCEPTION_VICTIM_INTEGRITY Integrity
Valid if the modified zone is Integrity.
DWORD ActiveCpuCount
The number of CPUs actually used by the guest.
INTOBJ_PERPROC_DESCRIPTOR * gDescriptors
Global array containing the per CPU protection descriptors for each InterruptObject array...
void IntAlertFillWinKmModule(const KERNEL_DRIVER *Driver, INTRO_MODULE *EventModule)
Saves kernel module information inside an alert.
INTSTATUS IntWinIntObjUnprotect(void)
Uninitializes the interrupt objects protection.
QWORD PcrGla
The guest linear address of the _KPCR structure loaded by this CPU.
#define ZONE_WRITE
Used for write violation.
static INTSTATUS IntWinIntObjHandleModification(INTOBJ_PROT_DESCRIPTOR *Descriptor, QWORD ObjectGva, INTRO_ACTION *Action)
Handles the modification of an interrupt object.
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.
#define INT_STATUS_INSUFFICIENT_RESOURCES