66 RbInsertNode(&gWinProcTreeUserCr3, &Process->NodeUserCr3);
68 RbInsertNode(&gWinProcTreeEprocess, &Process->NodeEproc);
89 RbDeleteNode(&gWinProcTreeUserCr3, &Process->NodeUserCr3);
91 RbDeleteNode(&gWinProcTreeEprocess, &Process->NodeEproc);
139 list = gWinProcesses.
Flink;
140 while (list != &gWinProcesses)
144 if (pProc->
Pid == Pid)
184 if (!strcasecmp(pProc->
Name, Name))
282 QWORD flink, blink, prevFlink, nextBlink, pid, type;
285 #define IS_INVALID_PTR(ptr) !IS_KERNEL_POINTER_WIN(gGuest.Guest64, (ptr)) || \ 286 (gGuest.Guest64 && 0xffffffff00000000 == ((ptr) & 0xffffffff00000000)) || \ 287 (!gGuest.Guest64 && 0xffffffff == (ptr)) \ 334 if (nextBlink != Gva)
346 if (prevFlink != Gva)
384 imageName[
sizeof(imageName) - 1] = 0;
386 if (0 != strcasecmp(imageName,
"system"))
419 QWORD cr3, parentEproc;
430 ERROR(
"[ERROR] IntWinProcMapEprocess failed: 0x%08x\n", status);
451 LOG(
"[EPROCESS] Skipping process %llx which is being marked as deleted (flags = 0x%x)...\n", Eprocess, flags);
453 goto cleanup_and_exit;
455 else if (0 == (flags &
WIN_KM_FIELD(EprocessFlags, HasAddrSpace)))
457 LOG(
"[EPROCESS] Skipping process %llx which does not have an address space (flags = 0x%x)...\n",
460 goto cleanup_and_exit;
465 LOG(
"[EPROCESS] The list seems to have a circular loop on process 0x%016llx, will break iteration...\n",
468 goto cleanup_and_exit;
485 ERROR(
"[ERROR] IntWinProcCreateProcessObject failed for EPROC 0x%016llx with flags 0x%x: 0x%08x\n",
486 Eprocess, flags, status);
487 goto cleanup_and_exit;
520 #define PROCESSES_MAX_COUNT 65535 522 QWORD currentProcess = 0, count = 0, nextProcess = 0;
524 if (Callback == NULL)
530 if (currentProcess == 0)
538 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
545 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
552 status = Callback((currentProcess -
WIN_KM_FIELD(Process, ListEntry)), Aux);
568 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
578 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", nextProcess, status);
585 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", nextProcess, status);
596 ERROR(
"[ERROR] The guest linked list seem to be cyclical, a cycle has been detected on 0x%016llx\n",
610 #undef PROCESSES_MAX_COUNT 665 list = gWinProcesses.
Flink;
666 while (list != &gWinProcesses)
698 size_t totalHeapSize, freeHeapSize;
705 ERROR(
"[ERROR] IntQueryHeapSize failed: 0x%08x, will assume 'infinite' heap.\n", status);
706 totalHeapSize = 0xFFFFFFFFFFFFFFFF;
707 freeHeapSize = 0xFFFFFFFFFFFFFFFF;
710 TRACE(
"[INFO] Heap stats: total size: %zu bytes, free: %zu bytes\n", totalHeapSize, freeHeapSize);
750 else if (cr3p1 > cr3p2)
777 else if (cr3p1 > cr3p2)
829 PCHAR cmd = CommandLine;
832 while (list != &gWinProcesses)
844 len = snprintf(cmd, Length,
"%s %u ", pProc->
Name, pProc->
Pid);
850 if ((
DWORD)len >= Length)
874 while (list != &gWinProcesses)
880 memset(parentName, 0,
sizeof(parentName));
881 memset(realParentName, 0,
sizeof(realParentName));
892 strlcpy(parentName,
"<TERMINATED>",
sizeof(parentName));
901 strlcpy(parentName,
"<TERMINATED>",
sizeof(parentName));
905 NLOG(
" EPROCESS: 0x%016llx, CR3: 0x%016llx, PID: %d, Token: 0x%016llx, WOW64: %d, Name: %s, " 906 "Parent: 0x%016llx/%s, Real parent: 0x%016llx/%s, Prot Mask: 0x%08x, System: %d\n",
924 NLOG(
" 64 bit subsystem:\n");
932 list2 = list2->
Flink;
934 NLOG(
" MODULE : 0x%016llx, Size: 0x%08x, Protected: %d, Hooked: %d, Unpack Protected: %d, " 935 "Main Module: %d Path: \"%s\", hash: 0x%08x\n",
947 NLOG(
" 32 bit subsystem:\n");
955 list2 = list2->
Flink;
957 NLOG(
" MODULE : 0x%016llx, Size: 0x%08x, Protected: %d, Hooked: %d, " 958 "Unpack Protected: %d, Main Module: %d Path: \"%s\"\n",
964 NLOG(
" VAD tree:\n");
969 NLOG(
" VAS monitor:\n");
988 while (list != &gWinProcesses)
993 if (NULL != ProcessName && 0 != strcasecmp(ProcessName, pProc->
Name))
1014 LOG(
"Mitigation Flags are not available! 0x%08x 0x%08x\n",
1022 while (list != &gWinProcesses)
1028 static const PCHAR flagsText[] =
1030 "ControlFlowGuardEnabled",
1031 "ControlFlowGuardExportSuppressionEnabled",
1032 "ControlFlowGuardStrict",
1033 "DisallowStrippedImages",
1034 "ForceRelocateImages",
1035 "HighEntropyASLREnabled",
1036 "StackRandomizationDisabled",
1037 "ExtensionPointDisable",
1038 "DisableDynamicCode",
1039 "DisableDynamicCodeAllowOptOut",
1040 "DisableDynamicCodeAllowRemoteDowngrade",
1041 "AuditDisableDynamicCode",
1042 "DisallowWin32kSystemCalls",
1043 "AuditDisallowWin32kSystemCalls",
1044 "EnableFilteredWin32kAPIs",
1045 "AuditFilteredWin32kAPIs",
1046 "DisableNonSystemFonts",
1047 "AuditNonSystemFontLoading",
1048 "PreferSystem32Images",
1049 "ProhibitRemoteImageMap",
1050 "AuditProhibitRemoteImageMap",
1051 "ProhibitLowILImageMap",
1052 "AuditProhibitLowILImageMap",
1053 "SignatureMitigationOptIn",
1054 "AuditBlockNonMicrosoftBinaries",
1055 "AuditBlockNonMicrosoftBinariesAllowStore",
1056 "LoaderIntegrityContinuityEnabled",
1057 "AuditLoaderIntegrityContinuity",
1058 "EnableModuleTamperingProtection",
1059 "EnableModuleTamperingProtectionNoInherit",
1061 static const PCHAR flags2Text[] =
1063 "EnableExportAddressFilter",
1064 "AuditExportAddressFilter",
1065 "EnableExportAddressFilterPlus",
1066 "AuditExportAddressFilterPlus",
1067 "EnableRopStackPivot",
1068 "AuditRopStackPivot",
1069 "EnableRopCallerCheck",
1070 "AuditRopCallerCheck",
1073 "EnableImportAddressFilter",
1074 "AuditImportAddressFilter",
1085 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1095 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1100 NLOG(
"+ Mitigation Flags: 0x%08x\n", flags.
Flags);
1101 for (
DWORD i = 0; i < 32; i++)
1103 if (0 == (flags.
Flags & (1 << i)))
1110 NLOG(
"\t Bit %02d is set -> UNKNOWN\n", i);
1114 NLOG(
"\t Bit %02d is set -> %s\n", i, flagsText[i]);
1118 NLOG(
"+ Mitigation Flags 2: 0x%08x\n", flags2.
Flags);
1119 for (
DWORD i = 0; i < 32; i++)
1121 if (0 == (flags2.
Flags & (1 << i)))
1128 NLOG(
"\t Bit %02d is set -> UNKNOWN\n", i);
1132 NLOG(
"\t Bit %02d is set -> %s\n", i, flags2Text[i]);
1160 static DWORD sizeofNeededEprocess = 0;
1177 if (0 == sizeofNeededEprocess)
1181 if (sizeofNeededEprocess < gWinGuest->OsSpecificFields.Km.Process[field])
1203 sizeofNeededEprocess--;
1208 ERROR(
"[ERROR] Failed to map EPROCESS at address 0x%016llx, IntVirtMemMap failed: 0x%08x\n", Eprocess, status);
WINUM_PATH * Path
Module path.
#define IS_INVALID_PTR(ptr)
PWIN_PROCESS_SUBSYSTEM Subsystemx64
The x64 subsystem. Note that a 32 bit process on a 64 bit OS may have both subsystems valid...
#define CONTAINING_RECORD(List, Type, Member)
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
WINDOWS_GUEST * gWinGuest
Global variable holding the state of a Windows guest.
struct _WIN_OPAQUE_FIELDS::@212 Km
Kernel mode information.
RBTREE gWinProcTreeEprocess
Tree of all the processes inside the guest, using the _EPROCESS address as the key.
QWORD RealParentEprocess
The active EPROCESS at the moment of creation.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
#define INT_STATUS_OUT_OF_RANGE
DWORD ShouldProtHooks
TRUE if the module should be protected against hooks.
#define _Out_writes_bytes_(expr)
DWORD KernelSize
The size of the kernel.
void IntWinProcLstRemoveProcess(WIN_PROCESS_OBJECT *Process)
Removes a WIN_PROCESS_OBJECT structure from the process lists and trees.
int IntWinProcRbTreeNodeCompareUserCr3(RBNODE const *Left, RBNODE const *Right)
struct _LIST_ENTRY * Flink
BOOLEAN IntWinVadDump(VAD const *Vad, void *Context)
Prints a VAD structure.
RBTREE gWinProcTreeCr3
Tree of all the processes inside the guest, using the kernel CR3 as the key.
void FUNC_RbTreeNodeFree(RBNODE *Node)
#define INT_SUCCESS(Status)
#define MIN_HEAP_SIZE_PERCENT
Minimum amount of free heap needed in order to activate process protection.
INTSTATUS RbLookupNode(RBTREE *Tree, RBNODE *NodeToSearch, RBNODE **NodeFound)
INTSTATUS IntVasDump(QWORD Cr3)
Dump the monitored tables for the indicated Cr3.
void IntWinProcLstInsertProcess(WIN_PROCESS_OBJECT *Process)
Inserts a WIN_PROCESS_OBJECT structure into the process lists and trees.
#define INT_STATUS_NOT_NEEDED_HINT
PWIN_PROCESS_OBJECT IntWinProcFindObjectByPid(DWORD Pid)
Finds a process by its ID.
INTSTATUS IntKernVirtMemFetchWordSize(QWORD GuestVirtualAddress, void *Data)
Reads a guest pointer from the guest kernel memory.
INTSTATUS IntWinProcIsPsActiveProcessHead(QWORD Gva)
Checks if a guest memory area is the list head of the process list (PsActiveProcessHead) ...
int INTSTATUS
The status data type.
INTSTATUS RbInit(RBTREE *Tree, PFUNC_RbTreeNodeFree NodeFree, PFUNC_RbTreeNodeCompare NodeCompare)
int FUNC_RbTreeNodeCompare(RBNODE *Left, RBNODE *Right)
#define INT_STATUS_NOT_FOUND
DWORD IsProtected
TRUE if the module is actually hooked.
#define IMAGE_BASE_NAME_LEN
The maximum length of a process name.
INTSTATUS IntQueryHeapSize(size_t *TotalHeapSize, size_t *FreeHeapSize)
INTSTATUS IntWinProcGetNameFromEprocess(QWORD Eprocess, CHAR *Name)
Reads a process name from the guest memory.
QWORD VirtualBase
Guest virtual address of the loaded module.
void IntWinProcRbTreeNodeFree(RBNODE *Node)
The NodeFree routine for the process RBTREE structures.
QWORD ParentEprocess
The EPROCESS of the parent process.
DWORD Process[winKmFieldProcessEnd]
Information about the _EPROCESS structure. Indexed with values from WIN_KM_FIELD_PROCESS.
#define INT_STATUS_BREAK_ITERATION
Can be used by iteration callbacks to break the iteration early.
DWORD Wow64Process
TRUE if this is a 32 bit process on a 64 bit OS.
LIST_HEAD gWinProcesses
The list of all the processes inside the guest.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByName(CHAR const *Name, BOOLEAN MustBeSystem)
Finds a process by name.
QWORD Cr3
Process PDBR. Includes PCID.
QWORD PsActiveProcessHead
Guest virtual address of the PsActiveProcessHead kernel variable.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByEprocess(QWORD Eprocess)
Finds a process by the address of its _EPROCESS structure.
RBNODE NodeEproc
Entry within gWinProcTreeEprocess (RB Tree).
int IntWinProcRbTreeNodeCompareCr3(RBNODE const *Left, RBNODE const *Right)
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
BOOLEAN Guest64
True if this is a 64-bit guest, False if it is a 32-bit guest.
CHAR Name[IMAGE_BASE_NAME_LEN]
Process base name.
DWORD ShouldProtUnpack
TRUE if the module should be protected against unpack.
QWORD UserCr3
Process user PDBR. Includes PCID.
INTSTATUS IntWinProcMapEprocess(QWORD Eprocess, void **Ptr)
Maps a _EPROCESS structure.
INTSTATUS(* PFUNC_IterateListCallback)(QWORD Node, QWORD Aux)
INTSTATUS IntWinProcIterateGuestProcesses(PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the in-guest process list and calls Callback for each entry.
void IntWinProcLstUnsafeReInit(void)
Reinitializes the Windows process lists and trees, without doing any cleanup.
INTSTATUS IntWinProcGetNameFromInternalEprocess(QWORD Eprocess, CHAR *Name)
Get a process name from the internal Introcore buffers.
DWORD ProtectionMask
Protection mask: tells us what level of protection will be activated for this process.
WIN_OPAQUE_FIELDS OsSpecificFields
OS-dependent and specific information (variables, offsets, etc).
#define INT_STATUS_INVALID_DATA_STATE
QWORD KernelVa
The guest virtual address at which the kernel image.
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)
void IntWinProcDump(void)
Prints information about all the processes in the system.
size_t strlcpy(char *dst, const char *src, size_t dest_size)
PWIN_PROCESS_OBJECT IntWinProcFindObjectByUserCr3(QWORD Cr3)
Finds a process by its user CR3.
INTSTATUS IntWinProcCreateProcessObject(WIN_PROCESS_OBJECT **Process, QWORD EprocessAddress, PBYTE EprocessBuffer, QWORD ParentEprocess, QWORD RealParentEprocess, QWORD Cr3, DWORD Pid, BOOLEAN StaticScan)
Allocates a WIN_PROCESS_OBJECT structure for the given process.
DWORD Pid
Process ID (the one used by Windows).
static void InitializeListHead(LIST_ENTRY *ListHead)
enum _WIN_KM_FIELD_PROCESS WIN_KM_FIELD_PROCESS
Indexes in the WIN_OPAQUE_FIELDS.Km.Process array, containing offsets inside the _EPROCESS structure...
void RbPreinit(RBTREE *Tree)
#define UNREFERENCED_PARAMETER(P)
INTSTATUS IntWinVadWalkTree(PWIN_PROCESS_OBJECT Process, PFUNC_RbTreeWalkCallback Callback)
Walks the VAD tree of a process.
DWORD NameHash
The CRC32 hash of the name. Used for fast matching.
#define INT_STATUS_DATA_BUFFER_TOO_SMALL
#define WIN_KM_FIELD(Structure, Field)
Macro used to access kernel mode fields inside the WIN_OPAQUE_FIELDS structure.
#define INT_STATUS_INVALID_DATA_VALUE
QWORD OriginalTokenPtr
Original Token pointer inside EPROCESS (should never change).
INTSTATUS IntWinProcAdd(QWORD Eprocess, QWORD Aux)
Adds a new process to the Introcore list of processes.
PWIN_PROCESS_OBJECT IntWinProcFindObjectByCr3(QWORD Cr3)
Finds a process by its kernel CR3.
FUNC_RbTreeWalkCallback * PFUNC_RbTreeWalkCallback
BOOLEAN IntWinProcIsEnoughHeapAvailable(void)
Checks if enough heap is available in order to protect a new process.
#define INT_STATUS_INVALID_OBJECT_TYPE
INTSTATUS IntWinProcGetAgentsAsCli(PCHAR CommandLine, DWORD Length)
Returns the name and ID for all the processes injected as agents inside the guest.
LIST_HEAD ProcessModules
List of process modules.
void IntWinProcDumpVads(const char *ProcessName)
Prints information about the VADs loaded in a process.
__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.
RBNODE NodeUserCr3
Entry within gWinProcTreeUserCr3 (RB Tree).
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
QWORD EprocessAddress
This will be the address of the ActiveProcess field.
DWORD SystemProcess
TRUE if this is a system process.
GUEST_STATE gGuest
The current guest state.
#define _Function_class_(expr)
int IntWinProcRbTreeNodeCompareEproc(RBNODE const *Left, RBNODE const *Right)
void IntWinProcDumpEgFlags(void)
Prints the mitigation flags of a process.
void RbDeleteNode(RBTREE *Tree, RBNODE *Node)
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
#define LIST_HEAD_INIT(Name)
#define _Out_writes_z_(expr)
INTSTATUS RbInsertNode(RBTREE *Tree, RBNODE *Node)
#define INT_STATUS_NOT_INITIALIZED_HINT
char * utf16_for_log(const WCHAR *WString)
Converts a UTF-16 to a UTF-8 string to be used inside logging macros.
#define INT_STATUS_INVALID_PARAMETER_1
DWORD IsAgent
TRUE if this is an injected agent.
#define INT_STATUS_UNINITIALIZED_STATUS_VALUE
#define RB_TREE_INIT(Name, Free, Compare)
Initializes a RBTREE structure.
PWIN_PROCESS_SUBSYSTEM Subsystemx86
The x86 subsystem. Note that a 32 bit process on a 64 bit OS may have both subsystems valid...
RBNODE NodeCr3
Entry within gWinProcTreeCr3 (RB Tree).
DWORD IsMainModule
TRUE if this is the main module.
#define INT_STATUS_INVALID_PARAMETER_2
DWORD Size
Virtual size of the module.
#define PROCESSES_MAX_COUNT
#define _Analysis_assume_(expr)
RBTREE gWinProcTreeUserCr3
Tree of all the processes inside the guest, using the user-mode CR3 as the key/.
This structure describes a running process inside the guest.
WCHAR * Path
The string which represents the user-mode module path.