51 memzero(pModLoad,
sizeof(*pModLoad));
71 if (NULL != ReturnModule)
75 (
DWORD)(RetAddr - ReturnModule->VirtualBase),
97 ERROR(
"[ERROR] IntNotifyIntroEvent failed: 0x%08x\n", status);
141 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
142 goto _send_notification;
152 ERROR(
"[ERROR] Failed getting modified zone: 0x%08x\n", status);
153 goto _send_notification;
163 if (Module->DoubleAgentAlertSent)
165 goto _skip_send_nodification;
170 LOG(
"[MODULE] Suspicious DLL '%s' loaded BEFORE kernel32 at %llx:%x!\n",
171 utf16_for_log(Module->Path->Path), Module->VirtualBase, Module->Size);
176 WARNING(
"[WARNING] IntWinDagentSendDoubleAgentAlert failed: 0x%08x\n", status);
179 Module->DoubleAgentAlertSent =
TRUE;
182 _skip_send_nodification:
252 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
267 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
277 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
295 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
310 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
320 ERROR(
"[ERROR] IntVirtMemWrite failed: 0x%08x\n", status);
334 _In_ void *BlockObject,
384 if (NULL == pReturnModule)
386 ERROR(
"[ERROR] Could not find a return module\n");
404 goto _check_exc_and_send_alert;
417 if (!Module->SlackSpaceForVerifier)
420 goto _check_exc_and_send_alert;
423 if (NULL != pReturnModule &&
428 TRACE(
"[INFO] Return module name for this exec: `%s` (%016llx) for process: `%s` PID: %d dll: `%s`\n",
436 _check_exc_and_send_alert:
446 ERROR(
"[ERROR] IntWinDagentHandleDoubleAgent failed: 0x%08x\n", status2);
475 DWORD sectionRva = 0;
476 DWORD sectionCount = 0;
484 ERROR(
"[ERROR] IntPeIterateSections failed with status: 0x%08x\n", status);
489 for (
DWORD iSec = 0; iSec < sectionCount; iSec++, pSec++)
498 DWORD minSize = 0xFFFFFFFF;
504 for (
DWORD iNextSec = 0; iNextSec < sectionCount; iNextSec++, pNextSec++)
525 if (minSize >= minRequiredSize)
536 TRACE(
"[INFO] Found a good address 0x%016llx\n", Module->SlackSpaceForVerifier);
539 if (!found && Module->IsSuspicious)
541 WARNING(
"[WARNING] Did not found a valid slack space for verifier address, " 542 "will kill process on first execution!\n");
554 _In_ void *BlockObject,
597 if (Module->Subsystem->Process->ImageIsFromNativeSubsystem)
603 if (!Module->SlackSpaceForVerifier)
612 if (Module->FirstDoubleAgentExecDone)
616 if (NULL != Module->SlackSpaceSwapHandle)
618 TRACE(
"[INFO] [DAGENT] Slack space not swapped-in yet, will retry.\n");
625 Module->FirstDoubleAgentExecDone =
TRUE;
631 Module->SlackSpaceForVerifier,
638 &Module->SlackSpaceSwapHandle);
641 ERROR(
"[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
649 ERROR(
"[ERROR] IntWinDagentHandleVerifierReason called for reason %llu\n", Reason);
704 ERROR(
"[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
730 _In_ const void *BlockObject
747 if (BlockObject != Module->ModBlockObject)
752 Module->ModBlockObject = NULL;
772 for (i = 0; i <
ARRAYSIZE(gInitialDlls); i++)
774 if (Module->IsSystemModule &&
MODULE_MATCH(Module, &gInitialDlls[i]))
814 if (!Module->Subsystem->Process->ProtDoubleAgent)
820 if (Module->IsMainModule)
830 &Module->MainModHeadersSwapHandle);
833 ERROR(
"[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
838 if (Module->StaticScan)
844 if (Module->Subsystem->Process->ImageIsFromNativeSubsystem)
850 if ((Module->Subsystem->SubsystemType ==
winSubsys64Bit) && Module->Subsystem->Process->Wow64Process)
855 if ((0 == Module->VirtualBase) || (0 == Module->Size))
860 if (Module->SuspChecked)
867 Module->Subsystem->Process->IsVerifierLoaded =
TRUE;
883 Module->IsSuspicious = !Module->Subsystem->Kernel32LoadCount;
890 &Module->ModBlockObject);
893 ERROR(
"[ERROR] IntWinModBlockBlockModuleLoad failed: 0x%08x\n", status);
902 ERROR(
"[ERROR] IntWinModBlockRegisterCallbackForReason failed: 0x%08x\n", status);
907 ERROR(
"[ERROR] IntWinModBlockRemoveBlockObject failed: 0x%08x\n", status);
913 Module->SuspChecked =
TRUE;
WINUM_PATH * Path
Module path.
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
Execution through module load.
INTSTATUS IntPeGetSectionHeaderByRva(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD GuestRva, IMAGE_SECTION_HEADER *SectionHeader)
Given a relative virtual address, return the section header which describes the section the RVA lies ...
QWORD ReturnRip
The RIP from which the suspicious module was called.
static INTSTATUS IntWinModDagentSuspModCleanup(WIN_PROCESS_MODULE *Module, const void *BlockObject)
Callback which is called from module block mechanism before the object is destroyed.
An internal error occurred (no memory, pages not present, etc.).
static INTSTATUS IntWinDagentHandleSuspModExecution(WIN_PROCESS_MODULE *Module, void *BlockObject, QWORD DllHandle, QWORD Reason, QWORD Reserved, QWORD RetAddress, INTRO_ACTION *Action)
Callback for module block mechanism, being called whenever executions take place in the possible mali...
IG_ARCH_REGS Regs
The current state of the guest registers.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
#define INT_STATUS_SUCCESS
Measures user mode exceptions checks.
#define IMAGE_SUBSYSTEM_NATIVE
Do not unload the module.
static INTSTATUS IntWinDagentHandleDoubleAgent(WIN_PROCESS_MODULE *Module, const WIN_PROCESS_MODULE *ReturnModule, INTRO_ACTION *Action, QWORD RetAddr)
Handles a DoubleAgent module load.
#define MODULE_MATCH(m, p)
void IntAlertFillWinProcess(const WIN_PROCESS_OBJECT *Process, INTRO_PROCESS *EventProcess)
Saves information about a windows process inside an alert.
EVENT_MODULE_LOAD_VIOLATION ModuleLoad
INTSTATUS IntWinModHandlePreInjection(void *Context, QWORD Cr3, QWORD VirtualAddress)
Module base page-fault pre-injection callback.
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...
static BOOLEAN IntWinDagentIsInitialDll(WIN_PROCESS_MODULE *Module)
Check if a module is one of the modules listed in gInitialDlls.
#define IMAGE_SCN_MEM_WRITE
#define INT_SUCCESS(Status)
DWORD IsSuspicious
TRUE if the module is suspicious.
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
#define WINMODBLOCK_INVALID_VALUE
DllHandle, Reason and Reserved can be equal to WINMODBLOCK_INVALID_VALUE when something that is not t...
INTSTATUS IntVirtMemWrite(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer)
Writes data to a guest virtual memory range.
INTRO_MODULE Module
The loaded module.
#define INT_STATUS_NOT_NEEDED_HINT
Describes a user-mode originator.
int INTSTATUS
The status data type.
BOOLEAN ImageIsFromNativeSubsystem
TRUE if the process image is from the native subsystem.
BOOLEAN FirstDoubleAgentExecDone
A flag which is set in order to verify if the first execution (for init phase) is done on double agen...
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
Verifier provider initialization structures for 64-bit processes.
static INTSTATUS IntWinDagentHandleSlackWritable(void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, const BYTE *Data, DWORD DataSize, DWORD Flags)
Swapmem callback which is called when the desired area between suspicious module section was swapped-...
BOOLEAN IntPolicyProcIsBeta(const void *Process, QWORD Flag)
Checks if a process protection policy is in log-only mode.
Verifier provider initialization structures for 64-bit processes.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
QWORD IntAlertProcGetFlags(QWORD ProtectionFlag, const void *Process, INTRO_ACTION_REASON Reason, QWORD AdditionalFlags)
Returns the flags for an alert.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
QWORD SlackSpaceForVerifier
The address between sections on which we put the needed verifier structure on double agent...
PWIN_PROCESS_MODULE IntWinUmModFindByAddress(PWIN_PROCESS_OBJECT Process, QWORD Gva)
Searches for a user-mode module which contains the indicated guest virtual address.
INTRO_PROCESS Victim
The process in which the module has loaded.
QWORD Cr3
Process PDBR. Includes PCID.
#define ALERT_FLAG_BETA
If set, the alert is a BETA alert. No action was taken.
INTSTATUS IntWinDagentCheckSuspiciousDllLoad(WIN_PROCESS_MODULE *Module)
Checks if the given module is suspicious of loading through the double agent technique and calls the ...
GENERIC_ALERT gAlert
Global alert buffer.
struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR_32 RTL_VERIFIER_PROVIDER_DESCRIPTOR_32
Verifier provider initialization structures for 32-bit processes.
BOOLEAN IntPolicyProcTakeAction(QWORD Flag, void const *Process, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Returns the action that should be taken for a process protection option.
#define INT_STATUS_NOT_INITIALIZED
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.
CHAR Name[IMAGE_BASE_NAME_LEN]
Process base name.
INTSTATUS IntPeListSectionsHeaders(QWORD ImageBase, BYTE *ImageBuffer, DWORD ImageBufferSize, DWORD *FirstSectionOffset, DWORD *SectionCount)
Will get the offset to the first section header and the number of sections from the given module...
Event structure for suspicious module load into processes.
Sent for suspicious module loads alerts. See EVENT_MODULE_LOAD_VIOLATION.
#define SWAPMEM_OPT_RW_FAULT
If set, the PF will be generated with write access. Useful when CoW must be done. ...
void * SlackSpaceSwapHandle
Swap handle for the slack space page where we put verifier structures.
#define NAMEHASH_APISETSCHEMA
const PROTECTED_DLL_INFO gInitialDlls[]
#define INT_STATUS_INVALID_INTERNAL_STATE
CHAR RipSectionName[ALERT_MAX_SECTION_NAME_LEN]
The name of the section in which the function executed by the loaded module is found.
void IntAlertFillWinProcessCurrent(INTRO_PROCESS *EventProcess)
Saves information about the current Windows process inside an alert.
void * MainModHeadersSwapHandle
Needed for verifying if the process main module is from the Native subsystem or not (e...
struct _WIN_PROCESS_OBJECT * Process
The process object related to this subsystem.
union _IMAGE_SECTION_HEADER::@214 Misc
DWORD Pid
Process ID (the one used by Windows).
Process subsystem type 64 bit.
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.
static INTSTATUS IntWinDagentHandleSuspModHeaders(WIN_PROCESS_MODULE *Module, BYTE *Headers)
Callback called through module block mechanism when the suspicious module headers are in memory...
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
DWORD NameHash
The CRC32 hash of the name. Used for fast matching.
INTSTATUS IntPeValidateHeader(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD ImageBaseBufferSize, INTRO_PE_INFO *PeInfo, QWORD Cr3)
Validates a PE header.
Verifier provider initialization structures for 32-bit processes.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
INTSTATUS IntWinProcSendAllDllEventsForProcess(PWIN_PROCESS_OBJECT Process)
Send DLL load events for all modules loaded in all subsystems of a process.
BOOLEAN IntPolicyProcForceBetaIfNeeded(QWORD Flag, void *Process, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the process log-only mode is active.
#define _In_reads_bytes_(expr)
#define NAMEHASH_VERIFIER
#define PROC_OPT_PROT_DOUBLE_AGENT
Blocks double agent attacks (malicious DLL loading) (Windows only).
struct _RTL_VERIFIER_PROVIDER_DESCRIPTOR_64 RTL_VERIFIER_PROVIDER_DESCRIPTOR_64
Verifier provider initialization structures for 64-bit processes.
WCHAR * Name
The name of the module contained in the path.
INTRO_MODULE ReturnModule
The module which called the entry function of the suspicious module.
#define DLL_VERIFIER_PROVIDER
INTSTATUS IntExceptGetVictimProcess(void *Process, QWORD DestinationGva, DWORD Length, QWORD ZoneFlags, EXCEPTION_VICTIM_ZONE *Victim)
This function is used to get the information about the victim process for injection violations...
Exposes the types, constants and functions needed to block Windows module loads (used to block double...
WIN_SUBSYTEM_TYPE SubsystemType
Process subsystem type.
INTRO_ACTION Action
The action that was taken as the result of this alert.
int wstrcasecmp(const WCHAR *buf1, const WCHAR *buf2)
Verifier provider initialization structures for 32-bit processes.
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
static INTSTATUS IntWinDagentCheckNativeSubsystem(void *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, BYTE *Data, DWORD DataSize, DWORD Flags)
Swapmem callback for the main module headers of the possible affected process.
BOOLEAN IsVerifierLoaded
TRUE if app verifier is loaded.
INTRO_PROCESS CurrentProcess
The current process.
VCPU_STATE * gVcpu
The state of the current VCPU.
void IntAlertFillWinUmModule(const WIN_PROCESS_MODULE *Module, INTRO_MODULE *EventModule)
Fills information about a user mode module inside an alert.
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
struct _EVENT_MODULE_LOAD_VIOLATION::@319 Originator
Measures module load violation handling.
INTSTATUS IntWinModBlockBlockModuleLoad(WIN_PROCESS_MODULE *Module, WIN_MOD_BLOCK_FLAG Flags, PFUNC_IntWinModBlockCallback Callback, PFUNC_IntWinModBlockHeadersCallback HeadersCallback, PFUNC_IntWinModBlockCleanup CleanupCallback, void **BlockObject)
This function is invoked when a suspicious dll is loaded in order to analyze and block the dll load i...
PWIN_PROCESS_SUBSYSTEM Subsystem
Module subsystem.
INTSTATUS IntWinModBlockRegisterCallbackForReason(void *BlockObject, DWORD Reason, PFUNC_IntWinModBlockCallback Callback)
Registers a callback that is invoked when the blocked module's DllMain function is called with a give...
#define NAMEHASH_KERNEL32
CHAR ReturnRipSectionName[ALERT_MAX_SECTION_NAME_LEN]
The name of the section in which ReturnRip resides.
QWORD AddressOfVerifierData
The address received by DllMain where the pointer to verifier structure should be put...
#define ZONE_MODULE_LOAD
Used for exceptions for double agent.
#define ZONE_WRITE
Used for write violation.
static INTSTATUS IntWinDagentHandleVerifierReason(WIN_PROCESS_MODULE *Module, void *BlockObject, QWORD DllHandle, QWORD Reason, QWORD Reserved, QWORD RetAddress, INTRO_ACTION *Action)
Called by the module block mechanism when DllMain was called with a specific Reason, DLL_VERIFIER_PROVIDER in this case.
#define SWAPMEM_OPT_UM_FAULT
If set, the PF must be injected only while in user-mode. Use it when reading user-mode memory...
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.
static INTSTATUS IntWinDagentSendDoubleAgentAlert(const WIN_PROCESS_MODULE *Module, const WIN_PROCESS_MODULE *ReturnModule, INTRO_ACTION Action, INTRO_ACTION_REASON Reason, QWORD RetAddr)
Sends a DoubleAgent alert.
INTRO_VIOLATION_HEADER Header
The alert header.
INTSTATUS IntWinModBlockRemoveBlockObject(void *BlockObject)
This function is used in order to destroy a WIN_MOD_BLOCK_OBJECT structure.
WCHAR * Path
The string which represents the user-mode module path.