Bitdefender Hypervisor Memory Introspection
winummoduleblock.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "winummoduleblock.h"
6 #include "hook.h"
7 #include "swapmem.h"
8 #include "introcpu.h"
9 #include "winummodule.h"
10 
19 
20 
24 typedef struct _WIN_MOD_BLOCK_OBJECT
25 {
28 
31 
34 
37 
40 
43 
51 
52 
58 {
63 
64 
69 {
73 
74 
75 
76 static INTSTATUS
78  _In_opt_ void *Context,
79  _In_ void *Hook,
80  _In_ QWORD Address,
81  _Inout_ INTRO_ACTION *Action
82  )
100 {
101  WIN_MOD_BLOCK_OBJECT *pBlockObj = Context;
102  WIN_PROCESS_MODULE *pMod = pBlockObj->Module;
103  INTSTATUS status, status2;
104  IG_ARCH_REGS *regs = &gVcpu->Regs;
105  QWORD retAddr = 0, dllHandle, reserved;
106  DWORD addrSize, reason;
108  BOOLEAN bEntryPoint = TRUE;
109 
111  UNREFERENCED_PARAMETER(Address);
112 
113  if (regs->Cr3 != pMod->Subsystem->Process->Cr3)
114  {
115  *Action = introGuestAllowed;
116  return INT_STATUS_SUCCESS;
117  }
118 
120 
121  addrSize = pMod->Subsystem->SubsystemType == winSubsys64Bit ? 8 : 4;
122 
123  // get the return address from stack
124  status = IntVirtMemRead(regs->Rsp, addrSize, pMod->Subsystem->Process->Cr3, &retAddr, NULL);
125  if (!INT_SUCCESS(status))
126  {
127  ERROR("[ERROR] IntVirtMemRead failed: 0x%08x\n", status);
128  goto _continue;
129  }
130 
131  if ((DWORD)(regs->Rip - pMod->VirtualBase) != pBlockObj->EntryPoint)
132  {
133  WARNING("[WARNING] Something which is not the entry point was called for %s (Rip %llx rva %x Entry point %x)\n",
134  utf16_for_log(pMod->Path->Name), regs->Rip,
135  (DWORD)(regs->Rip - pMod->VirtualBase), pBlockObj->EntryPoint);
136  bEntryPoint = FALSE;
137  }
138 
139  // get the parameters of DllMain; from regs for x64 and from stack for x86
140  if (pMod->Subsystem->SubsystemType == winSubsys64Bit && bEntryPoint)
141  {
142  dllHandle = regs->Rcx;
143  reason = (DWORD)regs->Rdx;
144  reserved = regs->R8;
145  }
146  else if (bEntryPoint)
147  {
148  DWORD stackArr[3];
149 
150  status = IntVirtMemRead(regs->Rsp + addrSize, 3 * addrSize, pMod->Subsystem->Process->Cr3, stackArr, NULL);
151  if (!INT_SUCCESS(status))
152  {
153  ERROR("[ERROR] IntVirtMemRead failed: 0x%08x\n", status);
154  goto _exit;
155  }
156 
157  dllHandle = stackArr[0];
158  reason = stackArr[1];
159  reserved = stackArr[2];
160  }
161  else
162  {
163  dllHandle = WINMODBLOCK_INVALID_VALUE;
164  reason = WINMODBLOCK_INVALID_VALUE;
165  reserved = WINMODBLOCK_INVALID_VALUE;
166  }
167 
168  status = pBlockObj->Callback(pMod, pBlockObj, dllHandle, reason, reserved, retAddr, &action);
169 
170  *Action = MAX(action, *Action);
171 
172  if (!INT_SUCCESS(status))
173  {
174  WARNING("[WARNING] Block object callback returned: 0x%08x\n", status);
175  goto _exit;
176  }
177 
178  if (*Action == introGuestAllowed)
179  {
180  goto _exit;
181  }
182 
184  {
185  if (pCbList->Reason != reason)
186  {
187  continue;
188  }
189 
190  list_for_each(pCbList->Callbacks, REASON_CALLBACK_OBJECT, pCbObj)
191  {
192  status = pCbObj->ReasonCallback(pMod, pBlockObj, dllHandle, reason, reserved, retAddr, &action);
193 
194  *Action = MAX(action, *Action);
195 
196  if (!INT_SUCCESS(status))
197  {
198  ERROR("[ERROR] Callback for reason %u returned: 0x%08x\n", reason, status);
199  goto _exit;
200  }
201 
202  }
203  }
204 
205 _exit:
206  if (*Action == introGuestAllowed)
207  {
208  status = IntWinModBlockRemoveBlockObject(pBlockObj);
209  if (!INT_SUCCESS(status))
210  {
211  ERROR("[ERROR] IntWinModBlockRemoveBlockObject failed: 0x%08x\n", status);
212  }
213 
214  // If we allowed the execution, ignore the WINMODBLOCK_FLAG_KILL_ON_ERROR flag
215  status = INT_STATUS_SUCCESS;
216  goto _continue;
217  }
218  else if (*Action != introGuestNotAllowed)
219  {
220  goto _continue;
221  }
222 
223  if (bEntryPoint && !!(pBlockObj->Flags & winModBlockFlagUnloadAfterExec))
224  {
225  TRACE("[INFO] Forcing unload by returning FALSE for module %s\n", utf16_for_log(pMod->Path->Name));
226 
227  regs->Rax = FALSE;
228  }
229  else if (bEntryPoint && !!(pBlockObj->Flags & winModBlockFlagDoNotUnload))
230  {
231  regs->Rax = TRUE;
232  }
233 
234  regs->Rip = retAddr;
235 
236  // On x86 need to emulate RET 0xC for DllMain - when we are not sure if
237  // it is entrypoint or not, we will not clean stack.
238  regs->Rsp += pMod->Subsystem->SubsystemType == winSubsys64Bit || !bEntryPoint ? addrSize : 4 * addrSize;
239 
240  // We changed the RIP so we'll tell the integrator we did everything (otherwise on KVM some emulation
241  // will take place from the old RIP).
242  *Action = introGuestAllowedVirtual;
243 
244  // We shall propagate the status from Callback for the WINMODBLOCK_FLAG_KILL_ON_ERROR to take place.
245  status2 = IntSetGprs(gVcpu->Index, regs);
246  if (!INT_SUCCESS(status2))
247  {
248  ERROR("[ERROR] IntSetGprs failed: 0x%08x\n", status2);
249  }
250 
251 _continue:
253 
254  // We can't really rely on introGuestRetry. It is not guaranteed that no emulation will take place etc.
255  // IntroGuestRetry should be used only when the page with Rip is swapped out or when we are removing the hook...
256  // but, since it's the maximum action we'll use it and overwrite here
257  if (*Action == introGuestRetry)
258  {
259  *Action = introGuestAllowedVirtual;
260  }
261 
262  if (!INT_SUCCESS(status))
263  {
264  if (!!(pBlockObj->Flags & winModBlockFlagKillOnError))
265  {
266  WARNING("[WARNING] Status is %x and flag KILL_ON_ERROR given, will try to kill process...\n", status);
268  }
269  }
270 
271  return INT_STATUS_SUCCESS;
272 }
273 
274 
275 static INTSTATUS
277  _In_ void *Context,
278  _In_ QWORD Cr3,
279  _In_ QWORD VirtualAddress
280  )
295 {
297  UNREFERENCED_PARAMETER(VirtualAddress);
298 
299  PWIN_MOD_BLOCK_OBJECT pModBlock = (PWIN_MOD_BLOCK_OBJECT)Context;
300  if (NULL == pModBlock)
301  {
303  }
304 
305  PWIN_PROCESS_MODULE pMod = pModBlock->Module;
306  if (NULL == pMod)
307  {
309  }
310 
311  if (!IntWinVadIsInTree(pMod->Vad))
312  {
313  LOG("[WINMODULE] The VAD 0x%016llx belonging to module %s seems to not be inside the tree yet, "
314  "will postpone #PF...\n",
315  pMod->Vad->VadGva, utf16_for_log(pMod->Path->Path));
316 
318  }
319 
320  return INT_STATUS_SUCCESS;
321 }
322 
323 
324 static INTSTATUS
326  _In_ WIN_MOD_BLOCK_OBJECT *Context,
327  _In_ QWORD Cr3,
328  _In_ QWORD VirtualAddress,
329  _In_ QWORD PhysicalAddress,
330  _In_reads_bytes_(DataSize) BYTE *Data,
331  _In_ DWORD DataSize,
333  )
352 {
353  WIN_MOD_BLOCK_OBJECT *pBlockObj = Context;
354  WIN_PROCESS_MODULE *pMod = pBlockObj->Module;
355  INTSTATUS status;
356  IMAGE_SECTION_HEADER *pSec;
357  INTRO_PE_INFO peInfo = { 0 };
358 
359  UNREFERENCED_PARAMETER(VirtualAddress);
360  UNREFERENCED_PARAMETER(PhysicalAddress);
361  UNREFERENCED_PARAMETER(DataSize);
362  UNREFERENCED_PARAMETER(Flags);
363 
364  TRACE("[INFO] Headers for suspicious dll %s in memory!\n", utf16_for_log(pMod->Path->Path));
365 
366  pBlockObj->HeadersSwapHandle = NULL;
367 
369  Cr3,
370  &pBlockObj->ExecHookObject);
371  if (!INT_SUCCESS(status))
372  {
373  ERROR("[ERROR] IntHookObjectCreate failed: 0x%08x\n", status);
374  goto cleanup_and_exit;
375  }
376 
377  status = IntPeValidateHeader(pMod->VirtualBase, Data, DataSize, &peInfo, 0);
378  if (!INT_SUCCESS(status))
379  {
380  ERROR("[ERROR] IntPeValidateHeader failed: 0x%08x\n", status);
381  goto cleanup_and_exit;
382  }
383 
384  pBlockObj->EntryPoint = peInfo.EntryPoint;
385 
386  TRACE("[INFO] Hooking for execute for Virtual Base (0x%016llx)\n", pMod->VirtualBase);
387 
388  pSec = (IMAGE_SECTION_HEADER *)(Data + peInfo.SectionOffset);
389  for (DWORD iSec = 0; iSec < peInfo.NumberOfSections; iSec++, pSec++)
390  {
391  char name[9] = { 0 };
392 
393  memcpy(name, pSec->Name, 8);
394 
395  if ((QWORD)pSec->VirtualAddress + pSec->Misc.VirtualSize > pMod->Vad->PageCount * PAGE_SIZE)
396  {
397  INFO("[INFO] Skipping section from VA 0x%08x, size 0x%08x, which is larger than VadSize 0x%016llx\n",
398  pSec->VirtualAddress, pSec->Misc.VirtualSize, pMod->Vad->PageCount * PAGE_SIZE);
399  continue;
400  }
401 
402  if (!!(pSec->Characteristics & IMAGE_SCN_MEM_EXECUTE) &&
404  {
405  TRACE("[INFO] Hooking for execute section %s (0x%08x, 0x%08x)\n",
406  name, pSec->VirtualAddress, pSec->Misc.VirtualSize);
407  status = IntHookObjectHookRegion(pBlockObj->ExecHookObject,
408  Cr3,
409  pMod->VirtualBase + pSec->VirtualAddress,
413  pBlockObj,
414  0,
415  NULL);
416  if (!INT_SUCCESS(status))
417  {
418  ERROR("[ERROR] IntHookObjectHookRegion failed: 0x%08x\n", status);
419  goto cleanup_and_exit;
420  }
421  }
422  else
423  {
424 
425  LOG("[INFO] Skipping for execute section %s (0x%08x, 0x%08x)\n",
426  name, pSec->VirtualAddress, pSec->Misc.VirtualSize);
427  }
428  }
429 
430  if (NULL != pBlockObj->HeadersCallback)
431  {
432  status = pBlockObj->HeadersCallback(pMod, Data);
433  if (!INT_SUCCESS(status))
434  {
435  ERROR("[ERROR] Section callback returned: 0x%08x\n", status);
436  goto cleanup_and_exit;
437  }
438  }
439 
440 cleanup_and_exit:
441  if (!INT_SUCCESS(status))
442  {
443  if (pBlockObj->ExecHookObject)
444  {
446  }
447  }
448 
449  return INT_STATUS_SUCCESS;
450 }
451 
452 
453 INTSTATUS
460  _Inout_ void **BlockObject
461  )
485 {
486  WIN_MOD_BLOCK_OBJECT *pBlockObject;
487  INTSTATUS status = INT_STATUS_SUCCESS;
488 
489  if (NULL == Module)
490  {
492  }
493 
494  if (0 == Flags)
495  {
497  }
498 
499  if (NULL == Callback)
500  {
502  }
503 
504  if (NULL == BlockObject)
505  {
507  }
508 
509  if (Module->StaticScan)
510  {
512  }
513 
514  pBlockObject = HpAllocWithTag(sizeof(*pBlockObject), IC_TAG_WINMOD_BLOCK);
515  if (NULL == pBlockObject)
516  {
518  }
519 
520  pBlockObject->Callback = Callback;
521  pBlockObject->HeadersCallback = HeadersCallback;
522  pBlockObject->CleanupCallback = CleanupCallback;
523  pBlockObject->Flags = Flags;
524  pBlockObject->Module = Module;
525  InitializeListHead(&pBlockObject->ReasonCallbacksList);
526 
527  status = IntSwapMemReadData(Module->Subsystem->Process->Cr3,
528  Module->VirtualBase,
529  PAGE_SIZE,
531  pBlockObject,
532  0,
535  &pBlockObject->HeadersSwapHandle);
536  if (!INT_SUCCESS(status))
537  {
538  ERROR("[ERROR] IntSwapMemReadData failed: 0x%08x\n", status);
539  goto cleanup_and_exit;
540  }
541 
542  *BlockObject = pBlockObject;
543 
544 cleanup_and_exit:
545  if (!INT_SUCCESS(status))
546  {
547  if (NULL != pBlockObject)
548  {
550  }
551  }
552 
553  return status;
554 }
555 
556 
557 INTSTATUS
559  _In_ void *BlockObject,
560  _In_ DWORD Reason,
562  )
588 {
589  WIN_MOD_BLOCK_OBJECT *pObj = BlockObject;
590  BOOLEAN found = FALSE;
591  INTSTATUS status = INT_STATUS_SUCCESS;
592  REASON_CALLBACK_LIST_OBJECT *pFinalCbList = NULL;
593  REASON_CALLBACK_OBJECT *pCbObj = NULL;
594 
595  if (NULL == BlockObject)
596  {
598  }
599 
600  if (WINMODBLOCK_INVALID_VALUE == Reason)
601  {
603  }
604 
605  if (NULL == Callback)
606  {
608  }
609 
610  pCbObj = HpAllocWithTag(sizeof(*pCbObj), IC_TAG_WINMOD_CB_OBJ);
611  if (NULL == pCbObj)
612  {
614  }
615 
617  {
618  if (pCbList->Reason == Reason)
619  {
620  pFinalCbList = pCbList;
621  found = TRUE;
622  break;
623  }
624  }
625 
626  if (!found)
627  {
628  pFinalCbList = HpAllocWithTag(sizeof(*pFinalCbList), IC_TAG_WINMOD_CB_LIST);
629  if (NULL == pFinalCbList)
630  {
632  goto cleanup_and_exit;
633  }
634 
635  pFinalCbList->Reason = Reason;
636  InitializeListHead(&pFinalCbList->Callbacks);
637 
638  InsertTailList(&pObj->ReasonCallbacksList, &pFinalCbList->Link);
639  }
640 
641  pCbObj->ReasonCallback = Callback;
642 
643  InsertTailList(&pFinalCbList->Callbacks, &pCbObj->Link);
644 
645 cleanup_and_exit:
646  if (!INT_SUCCESS(status))
647  {
648  if (NULL != pCbObj)
649  {
651  }
652 
653  if (NULL != pFinalCbList)
654  {
656  }
657  }
658 
659  return status;
660 }
661 
662 
663 INTSTATUS
665  _Inout_ void *BlockObject
666  )
677 {
678  WIN_MOD_BLOCK_OBJECT *pObj = BlockObject;
679  INTSTATUS status = INT_STATUS_SUCCESS;
680  LIST_ENTRY *list, *list2;
681 
682  if (NULL == BlockObject)
683  {
685  }
686 
687  if (NULL != pObj->CleanupCallback)
688  {
689  status = pObj->CleanupCallback(pObj->Module, pObj);
690  if (!INT_SUCCESS(status))
691  {
692  ERROR("[ERROR] Cleanup callback returned: 0x%08x\n", status);
693  // Continue cleaning up, even if this failed.
694  }
695  }
696 
697  if (NULL != pObj->ExecHookObject)
698  {
700  if (!INT_SUCCESS(status))
701  {
702  ERROR("[ERROR] IntHookObjectDestroy failed: 0x%08x\n", status);
703  }
704  }
705 
706  if (NULL != pObj->HeadersSwapHandle)
707  {
709  if (!INT_SUCCESS(status))
710  {
711  ERROR("[ERROR] IntSwapMemRemoveTransaction failed: 0x%08x\n", status);
712  }
713  }
714 
715  list = pObj->ReasonCallbacksList.Flink;
716 
717  while (list != &pObj->ReasonCallbacksList)
718  {
720  list = list->Flink;
721 
722  list2 = pCbList->Callbacks.Flink;
723 
724  while (list2 != &pCbList->Callbacks)
725  {
727  list2 = list2->Flink;
728 
729  RemoveEntryList(&pCbObj->Link);
731  }
732 
733  RemoveEntryList(&pCbList->Link);
735  }
736 
738 
739  return status;
740 }
WINUM_PATH * Path
Module path.
Definition: winummodule.h:62
#define IMAGE_SCN_MEM_EXECUTE
Definition: winpe.h:472
#define _In_opt_
Definition: intro_sal.h:16
_Bool BOOLEAN
Definition: intro_types.h:58
#define CONTAINING_RECORD(List, Type, Member)
Definition: introlists.h:36
enum _WIN_MOD_BLOCK_FLAG WIN_MOD_BLOCK_FLAG
Used to provided blocking options.
#define ROUND_UP(what, to)
Definition: introdefs.h:158
struct _REASON_CALLBACK_OBJECT * PREASON_CALLBACK_OBJECT
uint8_t BYTE
Definition: intro_types.h:47
INTSTATUS IntHookObjectDestroy(HOOK_OBJECT_DESCRIPTOR **Object, DWORD Flags)
Destroy an entire hook object. All regions belonging to this object will be removed.
Definition: hook_object.c:357
void * HeadersSwapHandle
The swap handle used for reading the module headers.
IG_ARCH_REGS Regs
The current state of the guest registers.
Definition: guests.h:95
DWORD Index
The VCPU number.
Definition: guests.h:172
WIN_PROCESS_MODULE * Module
The Windows process module to be blocked.
struct _REASON_CALLBACK_OBJECT REASON_CALLBACK_OBJECT
A reason callback context (invoked for a given dllMain reason).
#define _In_
Definition: intro_sal.h:21
#define INT_STATUS_SUCCESS
Definition: introstatus.h:54
const VAD * Vad
The VAD which describes this module.
Definition: winummodule.h:88
Do not unload the module.
INTSTATUS IntWinModBlockRemoveBlockObject(void *BlockObject)
This function is used in order to destroy a WIN_MOD_BLOCK_OBJECT structure.
#define STATS_EXIT(id)
Definition: stats.h:160
A reason callback context (invoked for a given dllMain reason).
#define IC_TAG_WINMOD_CB_OBJ
Win um module call back object for reason (in DllMain)
Definition: memtags.h:122
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...
Definition: swapmem.c:417
struct _LIST_ENTRY * Flink
Definition: introlists.h:20
INTSTATUS(* PFUNC_IntWinModBlockCleanup)(WIN_PROCESS_MODULE *Module, const void *BlockObject)
This callback type will be invoked when IntWinModBlockRemoveBlockObject is called for cleanup purpose...
#define IC_TAG_WINMOD_CB_LIST
Win um module call back list for a reason (in DllMain)
Definition: memtags.h:121
#define INT_SUCCESS(Status)
Definition: introstatus.h:42
WIN_MOD_BLOCK_FLAG Flags
The flags that will determine the action the be taken in case a malicious module is detected...
QWORD SectionOffset
Offset of the first section header.
Definition: winpe.h:602
#define WINMODBLOCK_INVALID_VALUE
DllHandle, Reason and Reserved can be equal to WINMODBLOCK_INVALID_VALUE when something that is not t...
struct _REASON_CALLBACK_LIST_OBJECT * PREASON_CALLBACK_LIST_OBJECT
#define INT_STATUS_NOT_NEEDED_HINT
Definition: introstatus.h:317
void * ExecHookObject
The hook object placed on the executable sections.
#define ERROR(fmt,...)
Definition: glue.h:62
struct _WIN_MOD_BLOCK_OBJECT WIN_MOD_BLOCK_OBJECT
Windows module block object.
static INTSTATUS IntWinModBlockHandleExecution(void *Context, void *Hook, QWORD Address, INTRO_ACTION *Action)
This function is invoked when a hooked section belonging to the analyzed module starts executing...
#define HpAllocWithTag(Len, Tag)
Definition: glue.h:516
int INTSTATUS
The status data type.
Definition: introstatus.h:24
PFUNC_IntWinModBlockCleanup CleanupCallback
This callback is invoked before destroying the WIN_MOD_BLOCK_OBJECT associated with this module...
INTSTATUS IntInjectExceptionInGuest(BYTE Vector, QWORD Cr2, DWORD ErrorCode, DWORD CpuNumber)
Injects an exception inside the guest.
Definition: introcore.c:2264
QWORD VirtualBase
Guest virtual address of the loaded module.
Definition: winummodule.h:34
QWORD VadGva
The guest virtual address at which the corresponding Windows _MMVAD structure is located.
Definition: winvad.h:108
A reason callback structure (this can contain multiple callbacks to be invoked for a certain dllMain ...
#define LOG(fmt,...)
Definition: glue.h:61
Executions in suspicious DLL loads.
Definition: intro_types.h:263
#define INFO(fmt,...)
Definition: glue.h:59
QWORD Cr3
Process PDBR. Includes PCID.
Definition: winprocess.h:98
DWORD Reason
The dllMain reason.
#define _Inout_
Definition: intro_sal.h:20
INTSTATUS IntSwapMemRemoveTransaction(void *Transaction)
Remove a transaction.
Definition: swapmem.c:942
#define STATS_ENTER(id)
Definition: stats.h:153
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
Definition: introlists.h:87
unsigned long long QWORD
Definition: intro_types.h:53
#define TRUE
Definition: intro_types.h:30
UINT32 VirtualAddress
Definition: winpe.h:85
QWORD NumberOfSections
Number of sections.
Definition: winpe.h:603
#define IC_TAG_WINMOD_BLOCK
Win um module load-blocking objects.
Definition: memtags.h:120
LIST_ENTRY ReasonCallbacksList
A list of callbacks that will be invoked for different dllMain reasons.
#define HpFreeAndNullWithTag(Add, Tag)
Definition: glue.h:517
#define TRACE(fmt,...)
Definition: glue.h:58
BOOLEAN IntWinVadIsInTree(const VAD *Vad)
Checks if a VAD is inserted in a guest VAD tree.
Definition: winvad.c:3437
#define INT_STATUS_INVALID_PARAMETER_5
Definition: introstatus.h:74
#define INT_STATUS_INVALID_INTERNAL_STATE
Definition: introstatus.h:272
INTSTATUS(* PFUNC_IntWinModBlockCallback)(WIN_PROCESS_MODULE *Module, void *BlockObject, QWORD DllHandle, QWORD Reason, QWORD Reserved, QWORD RetAddress, INTRO_ACTION *Action)
This callbacks provided detection logic for Windows module loads.
struct _WIN_PROCESS_OBJECT * Process
The process object related to this subsystem.
Definition: winprocess.h:56
union _IMAGE_SECTION_HEADER::@214 Misc
INTSTATUS IntWinModBlockRegisterCallbackForReason(void *BlockObject, DWORD Reason, PFUNC_IntWinModBlockCallback Callback)
Registers a callback that is invoked when the blocked module&#39;s DllMain function is called with a give...
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
Definition: introlists.h:135
#define WARNING(fmt,...)
Definition: glue.h:60
Process subsystem type 64 bit.
Definition: winprocess.h:33
PFUNC_IntWinModBlockCallback Callback
The callback that will provided the detection logic.
static void InitializeListHead(LIST_ENTRY *ListHead)
Definition: introlists.h:69
#define PAGE_SIZE
Definition: common.h:70
#define UNREFERENCED_PARAMETER(P)
Definition: introdefs.h:29
PFUNC_IntWinModBlockHeadersCallback HeadersCallback
This callback is invoked when the module headers have been successfully read.
uint32_t DWORD
Definition: intro_types.h:49
UINT32 VirtualSize
Definition: winpe.h:83
static INTSTATUS IntModBlockHandlePreInjection(void *Context, QWORD Cr3, QWORD VirtualAddress)
This function is invoked before injecting the #PF used to read the module headers.
UINT32 Characteristics
Definition: winpe.h:92
DWORD EntryPoint
Entry point (RVA).
Definition: winpe.h:601
INTSTATUS IntPeValidateHeader(QWORD ImageBase, BYTE *ImageBaseBuffer, DWORD ImageBaseBufferSize, INTRO_PE_INFO *PeInfo, QWORD Cr3)
Validates a PE header.
Definition: winpe.c:131
enum _INTRO_ACTION INTRO_ACTION
Event actions.
#define _In_reads_bytes_(expr)
Definition: intro_sal.h:25
INTSTATUS IntSetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Sets the values of the guest GPRs.
Definition: introcpu.c:905
WCHAR * Name
The name of the module contained in the path.
Definition: winumpath.h:18
#define MAX(a, b)
Definition: introdefs.h:151
struct _REASON_CALLBACK_LIST_OBJECT REASON_CALLBACK_LIST_OBJECT
A reason callback structure (this can contain multiple callbacks to be invoked for a certain dllMain ...
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
Definition: introcore.c:627
#define PFEC_US
Definition: processor.h:85
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...
Exposes the types, constants and functions needed to block Windows module loads (used to block double...
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: winpe.h:468
DWORD EntryPoint
The entry point of the module.
WIN_SUBSYTEM_TYPE SubsystemType
Process subsystem type.
Definition: winprocess.h:57
LIST_ENTRY Link
Entry within REASON_CALLBACK_LIST_OBJECT::Callbacks.
#define VECTOR_PF
Definition: processor.h:116
QWORD PageCount
The number of 4K pages in the VAD.
Definition: winvad.h:110
Force the module to unload by returning FALSE.
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.
Definition: hook_object.c:132
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
Definition: introcore.c:2845
struct _WIN_MOD_BLOCK_OBJECT * PWIN_MOD_BLOCK_OBJECT
#define INT_STATUS_INVALID_PARAMETER_1
Definition: introstatus.h:62
VCPU_STATE * gVcpu
The state of the current VCPU.
Definition: guests.c:59
UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: winpe.h:79
LIST_ENTRY Link
Entry within WIN_MOD_BLOCK_OBJECT::ReasonCallbacksList.
static INTSTATUS IntModBlockHandleBlockModHeadersInMemory(WIN_MOD_BLOCK_OBJECT *Context, QWORD Cr3, QWORD VirtualAddress, QWORD PhysicalAddress, BYTE *Data, DWORD DataSize, DWORD Flags)
This function is invoked when the module headers have been successfully read.
Holds register state.
Definition: glueiface.h:30
Measures module load violation handling.
Definition: stats.h:37
Execute-access hook.
Definition: glueiface.h:300
PWIN_PROCESS_SUBSYSTEM Subsystem
Module subsystem.
Definition: winummodule.h:60
INTSTATUS(* PFUNC_IntWinModBlockHeadersCallback)(WIN_PROCESS_MODULE *Module, BYTE *Headers)
This callback type will be called for the suspicious module headers when they are swapped in...
#define list_for_each(_head, _struct_type, _var)
Definition: introlists.h:41
LIST_ENTRY Callbacks
A list of callbacks to be invoked for the given dllMain reason.
#define INT_STATUS_INVALID_PARAMETER_2
Definition: introstatus.h:65
INTSTATUS IntHookObjectCreate(DWORD ObjectType, QWORD Cr3, void **Object)
Create a new hook object.
Definition: hook_object.c:81
PFUNC_IntWinModBlockCallback ReasonCallback
The callback to be invoked.
#define SWAPMEM_OPT_UM_FAULT
If set, the PF must be injected only while in user-mode. Use it when reading user-mode memory...
Definition: swapmem.h:21
size_t SIZE_T
Definition: intro_types.h:60
#define FALSE
Definition: intro_types.h:34
Windows module block object.
#define INT_STATUS_INSUFFICIENT_RESOURCES
Definition: introstatus.h:281
#define INT_STATUS_INVALID_PARAMETER_3
Definition: introstatus.h:68
WCHAR * Path
The string which represents the user-mode module path.
Definition: winumpath.h:17