13 #define LIX_VDSO_GPA_HOOK_PAGE_COUNT 3 61 ERROR(
"[ERROR] IntExceptKernelGetOriginator failed with status: 0x%08x\n", status);
70 ERROR(
"[ERROR] IntExceptGetVictimEpt failed with status: 0x%08x\n", status);
134 ERROR(
"[ERROR] IntExceptUserGetOriginator failed with status: 0x%08x\n", status);
144 ERROR(
"[ERROR] IntExceptGetVictimEpt failed with status: 0x%08x\n", status);
203 memzero(pEptViol,
sizeof(*pEptViol));
246 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
332 _In_ char *FunctionName,
360 ERROR(
"[ERROR] IntKsymFindByName could not find map_vdso\n");
367 ERROR(
"[ERROR] Could not find %s in kallsyms\n", FunctionName);
372 while (funcStart < funcEnd)
377 ERROR(
"[ERROR] IntDecDecodeInstruction failed: %08x\n", status);
381 funcStart += instrux.Length;
383 if (ND_INS_MOV == instrux.Instruction &&
384 instrux.Operands[0].Type == ND_OP_REG &&
385 instrux.Operands[0].Info.Register.Reg == NDR_RDI)
387 if (instrux.Operands[1].Type == ND_OP_IMM)
389 rdiValue =
SIGN_EX_32(instrux.Operands[1].Info.Immediate.Imm);
391 else if (instrux.Operands[1].Type == ND_OP_MEM)
393 QWORD tmp = funcStart + instrux.Operands[1].Info.Memory.Disp;
397 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for 0x016%llx: 0x%08x\n", tmp, status);
406 ERROR(
"[ERROR] Unsupported operand type for <mov rdi, ...> instruction: %d\n",
407 instrux.Operands[1].Type);
413 if ((instrux.Instruction == ND_INS_CALLNR || instrux.Instruction == ND_INS_JMPNR) &&
414 instrux.Operands[0].Type == ND_OP_OFFS &&
415 mapVdsoAddr == (funcStart + instrux.Operands[0].Info.RelativeOffset.Rel))
463 ERROR(
"[ERROR] vdso_image_64 not found: 0x%08x\n", status);
471 ERROR(
"[ERROR] Failed fetching from vdso_image %llx: 0x%08x\n", vdsoImage, status);
478 ERROR(
"[ERROR] Failed fetching from vdso_image %llx: 0x%08x\n", vdsoImage, status);
484 WARNING(
"[WARNING] vdso size is too large: %llu!\n", vdsoSize);
496 WARNING(
"[WARNING] vdso_image_x32 not found: 0x%08x\n", status);
504 ERROR(
"[ERROR] Failed fetching from vdso_image_x32 %llx: 0x%08x\n", vdsoImage, status);
511 ERROR(
"[ERROR] Failed fetching from vdso_image_x32 %llx: 0x%08x\n", vdsoImage, status);
517 WARNING(
"[WARNING] vdso size is too large: %llu!\n", vdsoSize);
528 WARNING(
"[WARNING] 'vdso_start' not found\n");
535 WARNING(
"[WARNING] 'vdso_end' not found\n");
542 LOG(
"[INFO] Guest has been built without x32 ABI support!\n");
550 WARNING(
"[WARNING] 'vdso_end_x32' not found\n");
597 LOG(
"[LIX-VDSO] Will protect the vdso later...\n");
604 ERROR(
"[ERROR] IntLixVdsoFetchAddress failed with status: 0x%08x.\n", status);
611 for (
QWORD current = vdsoStart &
PAGE_MASK; (current < vdsoEnd) &&
618 WARNING(
"[WARNING] IntTranslateVirtualAddress failed with status: 0x%08x. Will retry later...\n", status);
633 ERROR(
"[ERROR] IntHookGpaSetHook failed: 0x%08x\n", status);
638 TRACE(
"[LIX-VDSO] Protecting VDSO physical page: 0x%llx.\n", physAddr);
666 ERROR(
"[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
689 ERROR(
"[ERROR] Failed setting hook on vdso: 0x%08x!\n", status);
712 ERROR(
"[ERROR] Failed setting hook on vdso: 0x%08x!\n", status);
757 ERROR(
"[ERROR] Failed to protect the vdso...\n");
762 if (!gInitVdsoSym.
Start)
764 WARNING(
"[WARNING] Failed finding 'init_vdso'. Some FPs may follow\n");
765 gInitVdsoSym.
Start = gInitVdsoSym.
End = 0;
769 if (!gTextPokeEarlySym.
Start)
771 WARNING(
"[WARNING] Failed finding 'text_poke_early'. Some FPs may follow\n");
772 gTextPokeEarlySym.
Start = gTextPokeEarlySym.
End = 0;
776 if (!gAddNopsSym.
Start)
778 WARNING(
"[WARNING] Failed finding 'add_nops'. Some FPs may follow\n");
779 gAddNopsSym.
Start = gAddNopsSym.
End = 0;
804 TRACE(
"[INFO] This kernel is built without VSYSCALL support!");
811 LOG(
"[INFO] Fixed VDSO is not present @ 0x%016llx (0x%08x)\n",
LIX_VDSO_FIXED, status);
820 ERROR(
"[ERROR] IntHookObjectCreate failed with status: 0x%08x\n", status);
838 ERROR(
"[ERROR] Failed setting hook on vsyscall with status: 0x%08x\n", status);
874 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed with status: 0x%08x.\n", status);
902 WARNING(
"[WARNING] IntLixVdsoFixedProtect failed: 0x%08x\n", status);
908 ERROR(
"[ERROR] IntLixVdsoResolveDynamicOffset failed with status: 0x%08x.\n", status);
915 WARNING(
"[WARNING] Dynamic VDSO cannot be protected for this guest\n");
919 ERROR(
"[ERROR] IntLixVdsoDynamicProtect failed: 0x%08x\n", status);
947 ERROR(
"[ERROR] IntHookGpaDeleteHook failed with status: 0x%08x\n", status);
Measures kernel mode exceptions checks.
struct _EVENT_EPT_VIOLATION::@284 Victim
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.
QWORD Cr3
The CR3 for this process.
static void IntLixVdsoHandleUserModeWrite(QWORD Address, INTRO_OBJECT_TYPE Type, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Handles vDSO modification (from user-mode) detected by the EPT mechanism.
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.
QWORD End
The end guest virtual address of ksym (exclusive).
INTSTATUS IntHookObjectDestroy(HOOK_OBJECT_DESCRIPTOR **Object, DWORD Flags)
Destroy an entire hook object. All regions belonging to this object will be removed.
BYTE Violation
The type of the access. It must be one of the IG_EPT_HOOK_TYPE values.
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.
static LIX_SYMBOL gAddNopsSym
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.
INTSTATUS IntLixStackTraceGetReg(QWORD Cr3, PIG_ARCH_REGS Registers, DWORD MaxNumberOfTraces, QWORD Flags, STACK_TRACE *StackTrace)
Retrieves a Kernel stack backtrace based on the register values.
QWORD Start
The start guest virtual address of ksym.
QWORD HookStartPhysical
The start of the monitored guest physical memory area for which this alert was generated.
#define INT_SUCCESS(Status)
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
Structure that describes a stack trace element.
QWORD Vdso32Start
The guest virtual address where the vDSO x32 starts.
#define INT_STATUS_NOT_NEEDED_HINT
DWORD NumberOfTraces
Number of elements inside Traces.
Describes a user-mode originator.
struct _EVENT_EPT_VIOLATION::@283 Originator
INTSTATUS IntLixVdsoFetchAddress(LIX_TASK_OBJECT *Task, QWORD *Address)
Fetch the guest virtual address of the vDSO mapped on the provided task.
int INTSTATUS
The status data type.
QWORD Vdso32End
The guest virtual address where the vDSO x32 end.
void IntLixVdsoUnprotect(void)
Remove protection for the vDSO image and VSYSCALL.
#define INT_STATUS_NOT_FOUND
Describes a kernel-mode originator.
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
INSTRUX Instruction
The current instruction, pointed by the guest RIP.
static INTSTATUS IntLixVdsoResolveImageAddress(char *FunctionName, QWORD *Address)
Parse the provided function and search the 'vdso_image...' address.
STACK_ELEMENT * Traces
Array describing the stack trace elements.
QWORD HookStartVirtual
The start of the monitored guest virtual memory area for which this alert was generated.
#define INTRO_OPT_PROT_KM_VDSO
Enable vDSO image protection (Linux only).
void * IntHookObjectFindRegion(QWORD Gva, void *HookObject, BYTE HookType)
Searches for a region of hooked memory inside the provided hook object.
INTSTATUS IntHookGpaSetHook(QWORD Gpa, DWORD Length, BYTE Type, PFUNC_EptViolationCallback Callback, void *Context, void *ParentHook, DWORD Flags, HOOK_GPA **Hook)
Places an EPT hook on the indicated memory range.
Describes a kernel driver.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
static INTSTATUS IntLixVdsoHandleWrite(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
Handles vDSO modification detected by the EPT mechanism.
INTRO_VIOLATION_HEADER Header
The alert header.
QWORD ZoneTypes
The types of the accessed memory area.
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.
GENERIC_ALERT gAlert
Global alert buffer.
enum _INTRO_OBJECT_TYPE INTRO_OBJECT_TYPE
The type of the object protected by an EPT hook.
void IntAlertFillLixKmModule(const KERNEL_DRIVER *Driver, INTRO_MODULE *EventModule)
Saves information about a kernel module inside an alert.
static LIX_SYMBOL gInitVdsoSym
#define LIX_VDSO_GPA_HOOK_PAGE_COUNT
static INTSTATUS IntLixVdsoDynamicProtectRelocate(void)
Protect the vDSO using GPA hooks.
#define ZONE_LIB_CODE
Used for a generic code zone.
static BOOLEAN IntLixVdsoIsInitWrite(QWORD Rip)
Checks if the write is over the vDSO on the initialization phase.
#define INT_STATUS_EXCEPTION_BLOCK
#define IS_KERNEL_POINTER_LIX(p)
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
struct _LINUX_GUEST::@126 Layout
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.
#define IN_RANGE(x, start, end)
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.
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...
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
static LIX_SYMBOL gTextPokeEarlySym
#define LIX_FIELD(Structure, Field)
Macro used to access fields inside the LIX_OPAQUE_FIELDS structure.
QWORD VdsoEnd
The guest virtual address where the vDSO ends.
QWORD ReturnAddress
The address where the current stack frame will return (@ ret)
INTSTATUS IntHookGpaDeleteHook(HOOK_GPA **Hook, DWORD Flags)
Permanently delete a GPA hook.
DWORD NameHash
The hash of the modified object.
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.
INTRO_EXEC_CONTEXT ExecContext
Information about the instruction that triggered the alert.
#define INT_STATUS_ALREADY_INITIALIZED_HINT
INTSTATUS IntExceptUserGetOriginator(void *Process, BOOLEAN ModuleWrite, QWORD Address, INSTRUX *Instrux, EXCEPTION_UM_ORIGINATOR *Originator)
This function is used to get the information about the user-mode originator.
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 INTSTATUS IntLixVdsoDynamicProtectNonRelocate(void)
Protect the vDSO using GVA hooks.
static void IntLixVdsoHandleKernelModeWrite(QWORD Address, INTRO_OBJECT_TYPE Type, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Handles vDSO modification (from kernel-mode) detected by the EPT mechanism.
Describes the modified zone.
QWORD DataEnd
The guest virtual address where the data ends.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
The name is the operating system vdso (valid only for Linux).
QWORD RoDataEnd
The guest virtual address where the read-only data ends.
DWORD Offset
The offset inside the page where the violation took place.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
static void * gVdsoGpaHook[LIX_VDSO_GPA_HOOK_PAGE_COUNT]
GUEST_STATE gGuest
The current guest state.
struct _LINUX_GUEST::@127 Vdso
QWORD Vsyscall
The guest virtual address of the vsyscall.
Virtual SYSCALL (user-mode, Linux-only).
The name is the operating system vsyscall (valid only for Linux).
INTRO_ACTION Action
The action that was taken as the result of this alert.
KERNEL_DRIVER * IntDriverFindByAddress(QWORD Gva)
Returns the driver in which Gva resides.
QWORD VirtualPage
The guest virtual page in which the access was made.
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.
Virtual dynamic shared object (user-mode, Linux-only).
#define INT_STATUS_NOT_INITIALIZED_HINT
#define INT_STATUS_INVALID_PARAMETER_1
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.
LIX_TASK_OBJECT * IntLixTaskGetCurrent(DWORD CpuNumber)
Finds the task that is currently running on the given CPU.
INTRO_MODULE Module
The module that did the malicious access.
Event structure for EPT violations.
Structure that describes a stack trace.
void IntAlertFillLixCurrentProcess(INTRO_PROCESS *EventProcess)
Saves the current Linux process inside an event.
LIX_TASK_OBJECT * IntLixTaskFindByPid(DWORD Pid)
Finds the Linux process having the provided PID.
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
QWORD VdsoStart
The guest virtual address where the vDSO starts.
INTSTATUS IntLixVdsoProtect(void)
Activates protection for the vDSO image and VSYSCALL.
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.
QWORD Gla
The accessed guest virtual address. Valid only for EPT exits.
INTSTATUS IntDecDecodeInstruction(IG_CS_TYPE CsType, QWORD Gva, void *Instrux)
Decode an instruction from the provided guest linear address.
static INTSTATUS IntLixVdsoHandleWriteCommon(void *Context, HOOK_GPA *Hook, QWORD Address, INTRO_ACTION *Action)
Handles vDSO modification detected by the EPT mechanism.
INTSTATUS IntHookObjectCreate(DWORD ObjectType, QWORD Cr3, void **Object)
Create a new hook object.
static INTSTATUS IntLixVdsoFixedProtect(void)
This function activates the protection for the VSYSCALL.
static INTSTATUS IntLixVdsoResolveDynamicOffset(void)
Fetch the address of the 'vdso_image_64', 'vdso_image_x32' ksyms or the address of the 'vdso_start'...
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.
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
INTRO_OBJECT_TYPE Type
The type of the accessed memory area.
QWORD PhysicalPage
The guest physical page in which the access was made.
INTSTATUS IntLixVdsoDynamicProtect(void)
This function activates the protection for the vDSO image.