13 #define HAL_HEAP_PROT_PAGES_EXEC 0x20 42 memzero(pEptViol,
sizeof(*pEptViol));
65 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
104 memzero(&victim,
sizeof(victim));
105 memzero(&originator,
sizeof(originator));
110 exitAfterInformation =
FALSE;
116 exitAfterInformation =
TRUE;
120 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
122 exitAfterInformation =
TRUE;
134 ERROR(
"[ERROR] Failed getting zone details: 0x%08x\n", status);
135 exitAfterInformation =
TRUE;
138 if (exitAfterInformation)
190 DWORD instructionStart;
192 BYTE buffer[1] = { 0xC3 };
204 LOG(
"[HAL] Code from hal heap (GVA 0x%016llx --- GPA 0x%016llx) has been executed from 0x%016llx.\n",
211 ERROR(
"[ERROR] IntGetCurrentMode failed: 0x%08x\n", status);
219 TRACE(
"[HAL] Real mode execution detected.\n");
227 if (NULL == memoryArea)
233 if ((!
INT_SUCCESS(status)) && (0 == memAreaLength))
235 WARNING(
"[WARNING] IntKernVirtMemRead failed: %08x\n", status);
244 while (instructionStart < memAreaLength)
249 memAreaLength - instructionStart, csType, &instrux);
256 if (ND_INS_VMCALL == instrux.Instruction)
262 instructionStart += instrux.Length;
270 LOG(
"[HAL] Page %llx (physical %llx) seems to be the hypercall page. Will stop monitoring it...\n",
278 memzero(&victim,
sizeof(victim));
279 memzero(&originator,
sizeof(originator));
287 exitAfterInformation =
TRUE;
291 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed: %08x\n", status);
293 exitAfterInformation =
TRUE;
299 ERROR(
"[ERROR] IntExceptGetVictimEpt failed: %08x\n", status);
301 exitAfterInformation =
TRUE;
304 if (exitAfterInformation)
318 memzero(pEptViol,
sizeof(*pEptViol));
341 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
353 LOG(
"[HAL] Injecting ret instruction @ GVA 0x%016llx\n", gva);
359 ERROR(
"[ERROR] Could not inject ret! Status: %08x\n", status);
391 BYTE const *pOriginal = NULL;
398 pOriginal = IntegrityRegion->OriginalContent;
403 (((IntegrityRegion->Gva + IntegrityRegion->Length - 1) &
PAGE_MASK) == (IntegrityRegion->Gva &
PAGE_MASK));
408 ERROR(
"[ERROR] Failed to map GVA 0x%016llx: 0x%x\n", IntegrityRegion->Gva, status);
409 goto _cleanup_and_exit;
416 QWORD originalValue = 0;
421 originalValue = *(
QWORD *)((
size_t)pOriginal + (size_t)offset);
422 newValue = *(
QWORD *)((
size_t)pPage + (size_t)offset);
426 originalValue = *(
DWORD *)((
size_t)pOriginal + (size_t)offset);
427 newValue = *(
DWORD *)((
size_t)pPage + (size_t)offset);
430 if (newValue != originalValue)
432 DWORD currentOffset = offset;
434 memzero(&victim,
sizeof(victim));
436 memzero(&originator,
sizeof(originator));
441 ERROR(
"[ERROR] IntExceptGetVictimIntegrity failed: 0x%08x\n", status);
447 TRACE(
"[INFO] IntExceptGetOriginatorFromModification failed: 0x%08x\n", status);
458 LOG(
"[INTEGRITY VIOLATION] HalDispatchTable modification at 0x%016llx : 0x%x " 459 "(index %d). New Value = 0x%016llx, Old Value = 0x%016llx\n",
460 IntegrityRegion->Gva, offset, offset /
gGuest.
WordSize, newValue, originalValue);
464 LOG(
"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (B) ROOTKIT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n");
468 LOG(
"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ROOTKIT ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n");
503 ERROR(
"[ERROR] IntIntegrityRecalculate failed: 0x%x\n", status);
512 memzero(pIntViolation,
sizeof(*pIntViolation));
576 memzero(pIntViol,
sizeof(*pIntViol));
578 pIntViol->
BaseAddress = Victim->Integrity.StartVirtualAddress;
579 pIntViol->
VirtualAddress = Victim->Integrity.StartVirtualAddress + Victim->Integrity.Offset;
581 pIntViol->
Size = Victim->Integrity.TotalLength;
617 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
657 ERROR(
"[ERROR] Failed getting integrity zone: 0x%08x\n", status);
659 exitAfterInformation =
TRUE;
666 exitAfterInformation =
TRUE;
670 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
672 exitAfterInformation =
TRUE;
675 if (exitAfterInformation)
703 IntegrityRegion->OriginalContent);
706 ERROR(
"[ERROR] IntKernVirtMemPatchWordSize failed: 0x%08x\n", status);
735 QWORD hookAddrStart, hookAddrEnd;
751 hookAddrEnd = hookAddrStart + gHalData.
HalHeapSize;
756 ERROR(
"[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
760 for (
QWORD gva = hookAddrStart; gva < hookAddrEnd; gva +=
PAGE_SIZE)
768 WARNING(
"[WARNING] Cannot protect hal heap page 0x%016llx\n", gva);
775 WARNING(
"[WARNING] Cannot protect hal heap page 0x%016llx (GPA 0x%016llx)\n", gva, gpa);
781 WARNING(
"[WARNING] Will not protect hal heap page 0x%016llx because it translates to physical page 0\n",
798 ERROR(
"[ERROR] IntHookObjectHookRegion failed: %08x Region (0x%016llx, 0x%016llx)\n",
803 TRACE(
"[HAL] Hooking region (0x%016llx, 0x%016llx) against executions\n", gva, gva +
PAGE_SIZE);
828 TRACE(
"[HAL] Removing Hal Heap hook...\n");
865 ERROR(
"[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
880 ERROR(
"[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
905 TRACE(
"[HAL] Removing Hal Interrupt Controller hook...\n");
948 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%x\n", status);
973 TRACE(
"[HAL] Removing Hal Dispatch Table hook...\n");
978 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed with status: 0x%08X\n", status);
1026 ERROR(
"[ERROR] IntIntegrityAddRegion failed: 0x%x\n", status);
1052 TRACE(
"[HAL] Removing HalPerformanceCounter hook...\n");
1057 ERROR(
"[ERROR] IntIntegrityRemoveRegion failed: 0x%08X\n", status);
1087 #define MAX_INT_CTRL_COUNT 20 1090 QWORD functionPointer;
1091 QWORD functionOffset;
1093 QWORD initialInterruptController = 0;
1094 QWORD halFunction = 0;
1095 QWORD entriesOutsideTheHalHeap = 0;
1103 initialInterruptController = CheckedAddress;
1104 while (maxInterruptControllerCount)
1117 if (initialInterruptController < HalHeap)
1121 entriesOutsideTheHalHeap++;
1124 if (CheckedAddress == initialInterruptController && entriesOutsideTheHalHeap <= 1)
1130 maxInterruptControllerCount--;
1142 functionPointer <= CheckedAddress +
WIN_KM_FIELD(Ungrouped, HalIntCtrlTypeMaxOffset);
1151 if (0 == halFunction)
1153 foundFunctions =
TRUE;
1158 if (foundFunctions && (2 == (
DWORD)halFunction))
1163 if (((halFunction < gHalData.OwnerHalModule->BaseVa) ||
1170 foundFunctions =
TRUE;
1173 if (!foundFunctions || 2 != (
DWORD)halFunction)
1178 functionOffset = functionPointer - CheckedAddress;
1179 if (functionOffset <
WIN_KM_FIELD(Ungrouped, HalIntCtrlTypeMinOffset) ||
1180 functionOffset >
WIN_KM_FIELD(Ungrouped, HalIntCtrlTypeMaxOffset))
1189 #undef MAX_INT_CTRL_COUNT 1190 #undef MAX_INT_CTRL_TYPE_OFFSET 1191 #undef MIN_INT_CTRL_TYPE_OFFSET 1214 #define MAX_LIST_ITERATIONS_HAL_PERF 20 1216 DWORD numberOfOutsideHalHeap = 0;
1217 QWORD halPerfFunctionPtr = 0;
1227 nextList = HalPerfCandidate;
1240 numberOfOutsideHalHeap++;
1243 if (numberOfOutsideHalHeap > 1)
1248 if (nextList == HalPerfCandidate)
1261 &halPerfFunctionPtr);
1267 if (halPerfFunctionPtr < gHalData.OwnerHalModule->BaseVa ||
1275 #undef MAX_LIST_ITERATIONS_HAL_PERF 1300 #define MAX_INSTRUCTIONS_SEARCH 10 1303 INSTRUX instrux = { 0 };
1305 QWORD halPerfPtr = 0;
1308 QWORD currentRip = 0;
1309 QWORD instruxOffset = 0;
1325 "KeQueryPerformanceCounter",
1330 ERROR(
"[ERROR] IntPeFindExportByName failed: 0x%08x\n", status);
1335 instruxOffset = rva;
1339 if (instruxOffset + ND_MAX_INSTRUCTION_LENGTH >= buffSize)
1341 ERROR(
"[ERROR] The instruction at 0x%016llx resides outside the buffer!", currentRip);
1346 buffSize - instruxOffset,
1351 ERROR(
"[ERROR] IntDecDecodeInstructionFromBuffer failed: 0x%08x\n", status);
1355 currentRip += instrux.Length;
1356 instruxOffset += instrux.Length;
1358 if (instrux.Instruction == ND_INS_MOV &&
1359 instrux.ExpOperandsCount == 2 &&
1360 instrux.Operands[1].Type == ND_OP_MEM)
1362 QWORD possibleHalPerf = 0;
1365 if (
gGuest.
Guest64 && !instrux.Operands[1].Info.Memory.IsRipRel)
1373 (instrux.Operands[1].Info.Memory.HasBase ||
1374 instrux.Operands[1].Info.Memory.HasIndex ||
1375 !instrux.Operands[1].Info.Memory.HasDisp))
1380 if (instrux.Operands[1].Info.Memory.IsRipRel)
1382 halPerfPtr = currentRip + instrux.Operands[1].Info.Memory.Disp;
1386 halPerfPtr = instrux.Operands[1].Info.Memory.Disp;
1392 WARNING(
"[WARNING] IntKernVirtMemFetchWordSize failed: 0x%08x\n", status);
1401 TRACE(
"[INFO] Found HalPerformanceCounter at 0x%016llx!\n", possibleHalPerf);
1419 ERROR(
"[ERROR] IntWinHalProtectHalPerfCounter failed: 0x%08x\n", status);
1424 #undef MAX_INSTRUCTIONS_SEARCH 1447 ERROR(
"[ERROR] IntWinHalFindPerformanceCounterInternal failed: 0x%08x\n", status);
1473 ERROR(
"[ERROR] IntSwapMemRemoveTransaction failed for HAL headers: 0x%08x\n", status);
1488 initEntry = initEntry->
Flink;
1493 ERROR(
"[ERROR] IntSwapMemRemoveTransaction failed for %llx:%x: 0x%08x\n",
1562 ERROR(
"[ERROR] Callback came after we have no more sections to read...\n");
1564 goto resume_and_exit;
1567 memcpy(gHalData.
HalBuffer + va, Data, DataSize);
1573 TRACE(
"[HAL] All sections from hal were read into buffer\n");
1578 ERROR(
"[ERROR] IntWinHalFinishRead failed: 0x%08x\n", status);
1583 if (Flags & SWAPMEM_FLAG_ASYNC_CALL)
1617 DWORD secCount, secStartOffset;
1632 ERROR(
"[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
1638 ERROR(
"[ERROR] Inconsistent MZPE image!\n");
1658 ERROR(
"[ERROR] Failed mapping VA 0x%016llx to host: 0x%08x\n",
1663 unmapNtHeaders =
TRUE;
1691 ERROR(
"[ERROR] Failed mapping VA 0x%016llx to host: 0x%08x\n",
1696 unmapNtHeaders =
TRUE;
1711 ERROR(
"[ERROR] Sections get outside the first page. We don't support this yet!\n");
1717 ERROR(
"[ERROR] Sections get outside the first page. We don't support this yet!\n");
1738 for (
DWORD i = 0; i < secCount; i++)
1740 DWORD secActualSize;
1749 ERROR(
"[ERROR] We cannot have a section starting at 0!\n");
1756 ERROR(
"[ERROR] We cannot have a section starting at 0!\n");
1767 ERROR(
"[ERROR] Section %d seems corrupted: sizeOfImage = 0x%x, secstart = 0x%x, secsize = 0x%x\n",
1788 ERROR(
"[ERROR] IntKernVirtMemRead failed for 0x%016llx -> 0x%016llx %s: 0x%08x\n",
1791 pSec->
Name, status);
1811 void *swapHandle = NULL;
1820 pSwp->
Size = secActualSize;
1824 WARNING(
"Section %d / %d is not in memory, will do a swap mem read\n", i, secCount);
1837 ERROR(
"[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
1842 if (NULL != swapHandle)
1849 if (retSize != secActualSize)
1851 ERROR(
"We requested %08x bytes, but got %08x!\n", secActualSize, retSize);
1863 TRACE(
"[HAL] All sections were present in memory!\n");
1868 ERROR(
"[ERROR] IntWinHalFinishRead failed: 0x%08x\n", status);
1996 QWORD halIntCtrlGva = 0;
1997 void *dataSectionMem = NULL;
2003 ERROR(
"[ERROR] IntPeGetSectionHeadersByName failed: 0x%08x, number of sections: %d\n", status, nrSec);
2021 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
2032 if (halIntCtrlGva < HalHeap || halIntCtrlGva >= HalHeap + HalHeapSize)
2039 *HalInterruptController = halIntCtrlGva;
2083 DWORD pteTableIndex = 0;
2084 QWORD ptePhysicalAddress = 0;
2085 QWORD ptPhysicalAddress = 0;
2086 QWORD halHeapStart = 0;
2087 QWORD deviceAddressCount = 0;
2090 QWORD fallbackHalHeapVA = 0;
2091 QWORD halInterruptController = 0;
2093 void *dataSectionMem = NULL;
2095 #define HAL_HEAP_ORIGINAL 0xFFFFFFFFF0000000 2096 #define MASK_DEVICE_ADDRESS_FEC 0x00000000fec00000 2097 #define MASK_DEVICE_ADDRESS_FED 0x00000000fed00000 2098 #define MASK_DEVICE_ADDRESS_FEE 0x00000000fee00000 2099 #define HAL_HEAP_PHYSICAL_ADDRESS 0x1000 2105 ERROR(
"[ERROR] IntPeGetSectionHeadersByName failed: 0x%08x, number of sections: %d\n", status, nrSec);
2120 ERROR(
"[ERROR] IntVirtMemMap failed: 0x%08x\n", status);
2149 ptePhysicalAddress = halHeapStartTranslation.
MappingsTrace[pteTableIndex];
2174 deviceAddressCount = 0;
2175 for (
DWORD i = 0; i < 512; i++)
2184 deviceAddressCount++;
2189 deviceAddressCount++;
2194 deviceAddressCount++;
2206 if (deviceAddressCount >= 2)
2210 &halInterruptController);
2216 TRACE(
"[HAL] Found HalInterruptController at 0x%016llx\n", halInterruptController);
2219 *HalInterruptController = halInterruptController;
2225 if (fallbackHalHeapVA)
2227 WARNING(
"[WARNING] We could not find the Hal Heap using the mapped devices - fallback using PA:0x1000 " 2228 "VA:%llx\n", fallbackHalHeapVA);
2231 &halInterruptController);
2234 TRACE(
"[HAL] Found HalInterruptController at 0x%016llx\n", halInterruptController);
2236 *HalHeapBaseAddress = fallbackHalHeapVA;
2237 *HalInterruptController = halInterruptController;
2243 ERROR(
"[ERROR] We could not find the Hal Heap using the fallback VA\n");
2248 ERROR(
"[ERROR] We could not find the Hal Heap using the mapped devices and there is no fallback address\n");
2259 #undef HAL_HEAP_ORIGINAL 2260 #undef MASK_DEVICE_ADDRESS_FEC 2261 #undef MASK_DEVICE_ADDRESS_FED 2262 #undef MASK_DEVICE_ADDRESS_FEE 2263 #undef HAL_HEAP_PHYSICAL_ADDRESS 2288 ERROR(
"[ERROR] IntPeFindKernelExport failed for 'HalDispatchTable': 0x%x\n", status);
2305 ERROR(
"[ERROR] Could not find the module containing the Hal\n");
2311 TRACE(
"[HAL] Found HalDispatchTable at %llx, size %d\n",
2319 QWORD halInterruptController = 0;
2323 LOG(
"[HAL] Unable to find the HAL heap\n");
2324 goto _skip_hal_heap;
2341 TRACE(
"[HAL] Hal Interrupt Controller/Performance Counter does not exist on Windows version %d!\n",
2343 goto _skip_hal_heap;
2348 QWORD halInterruptController = 0;
2350 &halInterruptController);
2353 ERROR(
"[ERROR] Could not find Hal Interrupt Controller!\n");
2354 goto _skip_hal_heap;
2364 ERROR(
"[ERROR] IntWinHalFindPerformanceCounter failed: 0x%08x\n", status);
2365 goto _skip_hal_heap;
2375 ERROR(
"[ERROR] IntWinHalHookHalDispatchTable failed: 0x%08x\n", status);
2385 ERROR(
"[ERROR] IntWinHalHookHalHeapExecs failed: 0x%08x\n", status);
2395 ERROR(
"[ERROR] IntWinHalHookHalIntCtrl failed: 0x%08x\n", status);
2424 ERROR(
"[ERROR] IntWinHalHookHalDispatchTable failed: 0x%08x\n", status);
2438 ERROR(
"[ERROR] IntWinHalHookHalHeapExecs failed: 0x%08x\n", status);
2452 ERROR(
"[ERROR] IntWinHalHookHalIntCtrl failed: 0x%08x\n", status);
2466 ERROR(
"[ERROR] IntWinHalProtectHalPerfCounter failed: 0x%08x\n", status);
Measures kernel mode exceptions checks.
#define WIN_HAL_HEAP_BASE_32
The base address of the HAL heap on 32-bit kernels.
INTSTATUS IntWinHalUnprotectHalHeapExecs(void)
Deactivates the HAL heap execution protection.
struct _IMAGE_NT_HEADERS64 * PIMAGE_NT_HEADERS64
QWORD PhysicalAddress
The physical address to which VirtualAddress translates to.
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.
void * HalHdrSwapHandle
HAL headers swap handle. Used only if HAL is not protected, and the headers are not read automaticall...
static int64_t _InterlockedExchange64(int64_t volatile *Target, int64_t Value)
#define CONTAINING_RECORD(List, Type, Member)
#define ROUND_UP(what, to)
#define VICTIM_HAL_DISPATCH_TABLE
Printable name used for introObjectTypeHalDispatchTable objects.
INTSTATUS IntWinHalProtectHalPerfCounter(void)
Enables protection on HalPerformanceCounter function pointer.
#define HAL_HEAP_PROT_PAGES_EXEC
The number of HAL heap pages to protect against executions.
struct _IMAGE_FILE_HEADER IMAGE_FILE_HEADER
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.
DWORD Size
The size of the access.
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.
INTSTATUS IntWinHalUnprotectHalPerfCounter(void)
Removes the protection on HalPerformanceCounter.
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
INTSTATUS IntHookRemoveChain(PHOOK_GPA HookGpa)
Removes a hook chain, starting with the given GPA hook.
static INTSTATUS IntWinHalReadHal(void)
Reads the whole Hal image in memory, including swapped-out sections.
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
INTSTATUS IntHookObjectDestroy(HOOK_OBJECT_DESCRIPTOR **Object, DWORD Flags)
Destroy an entire hook object. All regions belonging to this object will be removed.
static INTSTATUS IntWinHalFindHalHeapAndInterruptController(QWORD *HalHeapBaseAddress, QWORD *HalInterruptController)
Attempts to find the Hal Heap and the Hal Interrupt Controller address within the ...
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.
INTSTATUS IntPeFindKernelExport(const char *Name, QWORD *ExportGva)
Find an export inside the NT kernel image.
INTSTATUS IntWinHalUpdateProtection(void)
Updates any of the HAL protections.
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.
WIN_KERNEL_DRIVER Win
Valid only for Windows guests.
QWORD NewValue[8]
The written value. Only the first Size bytes are valid.
void * HalPerfIntegrityObj
The HAL Performance Counter integrity hook object.
DWORD KernelSize
The size of the kernel.
Event structure for integrity violations on monitored structures.
LIST_ENTRY InitSwapHandles
A list containing the swap handles for the swapped out sections which should be read in HalBuffer...
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.
static void IntWinHalSendAlert(EXCEPTION_VICTIM_ZONE const *Victim, EXCEPTION_KM_ORIGINATOR const *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Sends an introEventEptViolation for HAL alerts.
INTSTATUS IntSwapMemReadData(QWORD Cr3, QWORD VirtualAddress, DWORD Length, DWORD Options, void *Context, DWORD ContextTag, PFUNC_PagesReadCallback Callback, PFUNC_PreInjectCallback PreInject, void **SwapHandle)
Reads a region of guest virtual memory, and calls the indicated callback when all the data is availab...
struct _LIST_ENTRY * Flink
QWORD BaseVa
The guest virtual address of the kernel module that owns this driver object.
#define INT_SUCCESS(Status)
LIST_ENTRY Link
Link inside the WINDOWS_GUEST.InitSwapHandles list.
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
IMAGE_FILE_HEADER FileHeader
The action was not allowed because there was no reason to allow it.
BOOLEAN KernelBetaDetections
True if the kernel protection is in beta (log-only) mode.
struct _EVENT_INTEGRITY_VIOLATION::@304 Victim
QWORD IntHookGetGlaFromGpaHook(HOOK_GPA const *Hook, QWORD Address)
Gets the GLA from a GPA hook.
#define MASK_DEVICE_ADDRESS_FEE
PBYTE MzPeHeaders
The driver`s MZ/PE headers (cached internally).
#define INT_STATUS_NOT_NEEDED_HINT
INTSTATUS IntPeFindExportByNameInBuffer(QWORD ImageBase, BYTE *Buffer, DWORD BufferSize, const char *Name, DWORD *ExportRva)
Find the export name a Rva lies in.
#define ALERT_FLAG_ASYNC
If set, the alert was generated in an async manner.
KERNEL_DRIVER * Driver
The driver that's modifying the memory.
INTSTATUS IntPeGetSectionHeadersByName(QWORD ImageBase, BYTE *ImageBaseBuffer, PCHAR Name, DWORD NumberOfSectionHeadersAllocated, QWORD Cr3, IMAGE_SECTION_HEADER *SectionHeaders, DWORD *NumberOfSectionHeadersFilled)
Return all the section headers matching the indicated Name.
#define HpAllocWithTag(Len, Tag)
INTSTATUS IntKernVirtMemFetchWordSize(QWORD GuestVirtualAddress, void *Data)
Reads a guest pointer from the guest kernel memory.
#define INTRO_OPT_PROT_KM_HAL_HEAP_EXEC
Enable execution prevention on the Hal Heap when it is not ASLR'd (Windows only). ...
int INTSTATUS
The status data type.
QWORD Size
The size of the kernel module that owns this driver object.
DWORD OSVersion
Os version.
static INTSTATUS IntWinHalFinishRead(void)
This is the function called when the Hal is completely read.
static INTSTATUS IntWinHalSectionInMemory(WIN_INIT_SWAP *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
Handles the swap in of a Hal section done while the WIN_HAL_DATA.HalBuffer is read.
#define INT_STATUS_NOT_FOUND
Describes a kernel-mode originator.
#define WIN_HAL_HEAP_BASE_64
The base address of the HAL heap on 64-bit kernels.
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
#define WIN_BUILD_10_20H1
INTSTATUS IntWinHalCreateHalData(void)
Initializes gHalData.
#define HAL_DISPATCH_TABLE_PTR_COUNT
The number of entries inside the hal dispatch table.
Describes a kernel driver.
KERNEL_DRIVER * IntDriverFindByName(const void *Name)
Searches for a driver by its name.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
#define MAX_INSTRUCTIONS_SEARCH
INTRO_VIOLATION_HEADER Header
The alert header.
BOOLEAN IntPolicyCoreIsOptionBeta(QWORD Flag)
Checks if one of the kernel protection options is in log-only mode.
DWORD HalBufferSize
The size of HAL buffer.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
void * HalIntCtrlWriteHook
The HAL interrupt controller write hook object.
static INTSTATUS IntWinHalFindPerformanceCounterInternal(void)
Finds and protects if needed the HalPerformanceCounter structure.
INTSTATUS IntAlertFillCodeBlocks(QWORD Rip, QWORD Cr3, BOOLEAN Execute, INTRO_CODEBLOCKS *CodeBlocks)
Fills the code blocks pattern for an alert.
DWORD MappingsCount
The number of entries inside the MappingsTrace and MappingsEntries arrays.
INTSTATUS IntGetCurrentMode(DWORD CpuNumber, DWORD *Mode)
Read the current CS type.
#define ALERT_FLAG_BETA
If set, the alert is a BETA alert. No action was taken.
void IntAlertEptFillFromKmOriginator(const EXCEPTION_KM_ORIGINATOR *Originator, EVENT_EPT_VIOLATION *EptViolation)
Fills kernel mode originator information inside an EPT alert.
INTSTATUS IntWinHalProtectHalDispatchTable(void)
Activates the HAL dispatch table protection.
GENERIC_ALERT gAlert
Global alert buffer.
static INTSTATUS IntWinHalFindInterruptController(QWORD HalHeap, QWORD HalHeapSize, QWORD *HalInterruptController)
Attempts to find the Hal Interrupt Controller address within the .data section of Hal...
INTSTATUS IntIntegrityRecalculate(INTEGRITY_REGION *IntegrityRegion)
Recalculates the hash and reads the original content again for a given region.
static WIN_HAL_DATA gHalData
The HAL information.
INTSTATUS IntSwapMemRemoveTransaction(void *Transaction)
Remove a transaction.
DWORD Size
The size of the read.
DWORD HalHeapSize
The size of the HAL heap.
void IntAlertFillWriteInfo(const EXCEPTION_VICTIM_ZONE *Victim, INTRO_WRITE_INFO *WriteInfo)
Fills the write information for an alert.
#define INT_STATUS_EXCEPTION_BLOCK
static INTSTATUS IntWinHalHeadersInMemory(void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, void *Data, DWORD DataSize, DWORD Flags)
This callback is called as soon as all the HAL headers have been read using IntSwapMemReadData.
Hal interrupt controller.
DWORD Size
The size of the modified memory area.
void IntAlertEptFillFromVictimZone(const EXCEPTION_VICTIM_ZONE *Victim, EVENT_EPT_VIOLATION *EptViolation)
Fills the victim information inside an EPT alert.
static INTSTATUS IntWinHalHandleDispatchTableWrite(PINTEGRITY_REGION IntegrityRegion)
Handles modifications done to the HAL dispatch table.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
static INTSTATUS IntWinHalHandlePerfCounterModification(INTEGRITY_REGION *IntegrityRegion)
Integrity callback for detections of modifications over HalPerformanceCounter.
static void IntWinHalCancelRead(void)
Cancels the Hal module read.
#define INT_STATUS_UNSUCCESSFUL
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
#define INTRO_OPT_PROT_KM_HAL_PERF_CNT
Enable protection over HalPerformanceCounter's function pointer, which is called inside KeQueryPerfor...
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
#define ZONE_EXECUTE
Used for execute violation.
#define INTRO_OPT_PROT_KM_HAL_INT_CTRL
Enable Hal Interrupt Controller write protection.
void * HalDispatchIntegrityHook
The HAL dispatch table integrity hook object.
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
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.
static INTSTATUS IntWinHalHandleHalIntCtrlWrite(KERNEL_DRIVER *Context, HOOK_GPA const *Hook, QWORD Address, INTRO_ACTION *Action)
Handles writes done over the HAL interrupt controller.
INTRO_MODULE Module
The module that modified the monitored region.
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
Write protection over HalPerformanceCounter.
static int32_t _InterlockedExchange(int32_t volatile *Target, int32_t Value)
QWORD VirtualAddress
The guest virtual address which was modified.
static INTSTATUS IntWinHalFindPerformanceCounter(void)
Starts the process of finding the HalPerformanceCounter.
INTSTATUS IntDecDecodeInstructionFromBuffer(PBYTE Buffer, size_t BufferSize, IG_CS_TYPE CsType, void *Instrux)
Decode an instruction from the provided buffer.
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.
DWORD RemainingSections
The number of sections which are not yet read into HAL buffer.
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)
#define INT_STATUS_INVALID_INTERNAL_STATE
BYTE * HalBuffer
A buffer containing the whole HAL image.
static BOOLEAN IntWinHalIsIntController(QWORD CheckedAddress, QWORD HalHeap)
Checks if a guest memory range is the HAL interrupt controller.
#define MASK_DEVICE_ADDRESS_FED
INTSTATUS IntWinHalProtectHalHeapExecs(void)
Hooks the HAL heap against execution.
QWORD KernelVa
The guest virtual address at which the kernel image.
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.
void IntAlertFillWinProcessCurrent(INTRO_PROCESS *EventProcess)
Saves information about the current Windows process inside an alert.
union _IMAGE_SECTION_HEADER::@214 Misc
struct _IMAGE_NT_HEADERS * PIMAGE_NT_HEADERS32
BYTE WordSize
Guest word size. Will be 4 for 32-bit guests and 8 for 64-bit guests.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
INTSTATUS IntTranslateVirtualAddressEx(QWORD Gva, QWORD Cr3, DWORD Flags, VA_TRANSLATION *Translation)
Translates a guest virtual address to a guest physical address.
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
QWORD VirtualAddress
The guest virtual address that will be read.
#define SWAPMEM_FLAG_ASYNC_CALL
#define INT_STATUS_ALREADY_INITIALIZED_HINT
#define MASK_DEVICE_ADDRESS_FEC
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.
static void InitializeListHead(LIST_ENTRY *ListHead)
QWORD HalHeapAddress
The guest virtual address of the HAL heap.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
INTSTATUS IntWinHalUnprotectHalIntCtrl(void)
Deactivates the HAL interrupt controller write protection.
#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.
DWORD KernelBufferSize
The size of the KernelBuffer.
DWORD HalDispatchTableSize
The size of the HAL dispatch table.
KERNEL_DRIVER * OwnerHalModule
The hal.dll kernel module or ntoskrnl.exe.
INTSTATUS IntPeValidateHeader(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD ImageBaseBufferSize, INTRO_PE_INFO *PeInfo, QWORD Cr3)
Validates a PE header.
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
QWORD HalDispatchTableAddress
The guest virtual address of the HAL dispatch table.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
#define _In_reads_bytes_(expr)
QWORD OldValue[8]
The original value. Only the first Size bytes are valid.
INTSTATUS IntIntegrityRemoveRegion(void *Descriptor)
Removes an integrity region from the gIntegrityRegions list.
INTRO_WRITE_INFO WriteInfo
#define INT_STATUS_INVALID_OBJECT_TYPE
#define SWAPMEM_OPT_BP_FAULT
If set, the #PF will be generated from an int3 detour. Use this when injecting kernel PFs...
BOOLEAN IntWinHalIsHalPerf(QWORD HalPerfCandidate)
Verifies if the given pointer is the HalPerformanceCounter.
INTSTATUS IntGetEPTPageProtection(DWORD EptIndex, QWORD Gpa, BYTE *Read, BYTE *Write, BYTE *Execute)
__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.
QWORD Cr3
The value of the guest CR3 register when the event was generated.
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...
void IntWinHalUninit(void)
Frees any resources held by gHalData and removes all the HAL protections.
struct _IMAGE_SECTION_HEADER * PIMAGE_SECTION_HEADER
#define IMAGE_SCN_MEM_DISCARDABLE
Exploitation for Privilege Escalation.
QWORD MappingsTrace[MAX_TRANSLATION_DEPTH]
Contains the physical address of each entry within the translation tables.
EVENT_INTEGRITY_VIOLATION Integrity
#define HAL_HEAP_ORIGINAL
struct _EXCEPTION_KM_ORIGINATOR::@64 Original
struct _EVENT_INTEGRITY_VIOLATION::@302 Originator
INTRO_ACTION Action
The action that was taken as the result of this alert.
QWORD VirtualAddress
The translated virtual address.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
QWORD HalIntCtrlAddress
The guest virtual address of the HAL interrupt controller.
QWORD BaseAddress
The guest virtual address at which the monitored integrity region starts.
IMAGE_FILE_HEADER FileHeader
The initialization swap handle.
INTSTATUS IntHookObjectHookRegion(void *Object, QWORD Cr3, QWORD Gla, SIZE_T Length, BYTE Type, void *Callback, void *Context, DWORD Flags, HOOK_REGION_DESCRIPTOR **Region)
Hook a contiguous region of virtual memory inside the provided virtual address space.
#define VICTIM_HAL_PERFORMANCE_COUNTER
Printable name used for introObjectTypeHalPerfCounter objects.
__must_check INTSTATUS IntPhysMemMap(QWORD PhysAddress, DWORD Length, DWORD Flags, void **HostPtr)
Maps a guest physical address inside Introcore VA space.
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...
#define INT_STATUS_NOT_INITIALIZED_HINT
Encapsulates information about a virtual to physical memory translation.
BYTE * KernelBuffer
A buffer containing the entire kernel image.
KERNEL_DRIVER * KernelDriver
Points to the driver object that describes the kernel image.
#define INT_STATUS_INVALID_PARAMETER_1
#define INT_STATUS_NOT_SUPPORTED
INTRO_PROCESS CurrentProcess
The current process.
VCPU_STATE * gVcpu
The state of the current VCPU.
The action was blocked because there was no exception for it.
#define MAX_LIST_ITERATIONS_HAL_PERF
#define INTRO_OPT_PROT_KM_HAL_DISP_TABLE
Enable HDT (Hal Dispatch Table) protection (Windows only).
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
Sent for integrity violation alerts. See EVENT_INTEGRITY_VIOLATION.
#define HAL_HEAP_PHYSICAL_ADDRESS
static void IntWinHalSendPerfCntIntegrityAlert(EXCEPTION_VICTIM_ZONE *Victim, EXCEPTION_KM_ORIGINATOR *Originator, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Sends an introEventIntegrityViolation for detections of writes over HalPerformanceCounter.
DWORD SizeOfImage
Size of the image.
Event structure for EPT violations.
BOOLEAN Image64Bit
True if the image is 64 bit.
void IntAlertFillWinKmModule(const KERNEL_DRIVER *Driver, INTRO_MODULE *EventModule)
Saves kernel module information inside an alert.
Exploitation of Remote Services.
void * HalHeapExecHook
The HAL heap execution hook object.
void * SwapHandle
The actual swap handle returned by IntSwapMemRead.
INTSTATUS IntPhysMemUnmap(void **HostPtr)
Unmaps an address previously mapped with IntPhysMemMap.
#define IMAGE_SCN_MEM_NOT_PAGED
DWORD UntrustedEptIndex
The EPTP index of the untrusted EPT.
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.
QWORD HalPerfCounterAddress
The guest virtual address of the HAL performance counter.
static INTSTATUS IntWinHalHandleHalHeapExec(void *Context, HOOK_GPA *Hook, QWORD Address, INTRO_ACTION *Action)
Handles execution attempts from the HAL heap.
INTSTATUS IntHookObjectCreate(DWORD ObjectType, QWORD Cr3, void **Object)
Create a new hook object.
UINT16 SizeOfOptionalHeader
INTSTATUS IntWinHalProtectHalIntCtrl(void)
Protects the HAL interrupt controller against writes.
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 MAX_INT_CTRL_COUNT
#define INT_STATUS_INVALID_DATA_SIZE
#define INT_STATUS_INSUFFICIENT_RESOURCES
INTSTATUS IntWinHalUnprotectHalDispatchTable(void)
Deactivates the HAL dispatch table protection.