66 list = gWinProcesses.
Flink;
67 while (list != &gWinProcesses)
71 if (pProc->
Pid == Pid)
111 if (!strcasecmp(pProc->
Name, Name))
209 QWORD flink, blink, prevFlink, nextBlink, pid, type;
212 #define IS_INVALID_PTR(ptr) !IS_KERNEL_POINTER_WIN(gGuest.Guest64, (ptr)) || \ 213 (gGuest.Guest64 && 0xffffffff00000000 == ((ptr) & 0xffffffff00000000)) || \ 214 (!gGuest.Guest64 && 0xffffffff == (ptr)) \ 261 if (nextBlink != Gva)
273 if (prevFlink != Gva)
311 imageName[
sizeof(imageName) - 1] = 0;
313 if (0 != strcasecmp(imageName,
"system"))
346 QWORD cr3, parentEproc;
357 ERROR(
"[ERROR] IntWinProcMapEprocess failed: 0x%08x\n", status);
378 LOG(
"[EPROCESS] Skipping process %llx which is being marked as deleted (flags = 0x%x)...\n", Eprocess, flags);
380 goto cleanup_and_exit;
382 else if (0 == (flags &
WIN_KM_FIELD(EprocessFlags, HasAddrSpace)))
384 LOG(
"[EPROCESS] Skipping process %llx which does not have an address space (flags = 0x%x)...\n",
387 goto cleanup_and_exit;
392 LOG(
"[EPROCESS] The list seems to have a circular loop on process 0x%016llx, will break iteration...\n",
395 goto cleanup_and_exit;
412 ERROR(
"[ERROR] IntWinProcCreateProcessObject failed for EPROC 0x%016llx with flags 0x%x: 0x%08x\n",
413 Eprocess, flags, status);
414 goto cleanup_and_exit;
447 #define PROCESSES_MAX_COUNT 65535 449 QWORD currentProcess = 0, count = 0, nextProcess = 0;
451 if (Callback == NULL)
457 if (currentProcess == 0)
465 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
472 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
479 status = Callback((currentProcess -
WIN_KM_FIELD(Process, ListEntry)), Aux);
495 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", currentProcess, status);
505 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", nextProcess, status);
512 ERROR(
"[ERROR] Failed getting the Flink value of EPROCESS @ 0x%016llx: 0x%08x\n", nextProcess, status);
523 ERROR(
"[ERROR] The guest linked list seem to be cyclical, a cycle has been detected on 0x%016llx\n",
537 #undef PROCESSES_MAX_COUNT 592 list = gWinProcesses.
Flink;
593 while (list != &gWinProcesses)
625 size_t totalHeapSize, freeHeapSize;
632 ERROR(
"[ERROR] IntQueryHeapSize failed: 0x%08x, will assume 'infinite' heap.\n", status);
633 totalHeapSize = 0xFFFFFFFFFFFFFFFF;
634 freeHeapSize = 0xFFFFFFFFFFFFFFFF;
637 TRACE(
"[INFO] Heap stats: total size: %zu bytes, free: %zu bytes\n", totalHeapSize, freeHeapSize);
677 else if (cr3p1 > cr3p2)
704 else if (cr3p1 > cr3p2)
756 PCHAR cmd = CommandLine;
759 while (list != &gWinProcesses)
771 len = snprintf(cmd, Length,
"%s %u ", pProc->
Name, pProc->
Pid);
796 while (list != &gWinProcesses)
802 memset(parentName, 0,
sizeof(parentName));
803 memset(realParentName, 0,
sizeof(realParentName));
814 strlcpy(parentName,
"<TERMINATED>",
sizeof(parentName));
823 strlcpy(parentName,
"<TERMINATED>",
sizeof(parentName));
827 NLOG(
" EPROCESS: 0x%016llx, CR3: 0x%016llx, PID: %d, Token: 0x%016llx, WOW64: %d, Name: %s, " 828 "Parent: 0x%016llx/%s, Real parent: 0x%016llx/%s, Prot Mask: 0x%08x, System: %d\n",
846 NLOG(
" 64 bit subsystem:\n");
854 list2 = list2->
Flink;
856 NLOG(
" MODULE : 0x%016llx, Size: 0x%08x, Protected: %d, Hooked: %d, Unpack Protected: %d, " 857 "Main Module: %d Path: \"%s\", hash: 0x%08x\n",
869 NLOG(
" 32 bit subsystem:\n");
877 list2 = list2->
Flink;
879 NLOG(
" MODULE : 0x%016llx, Size: 0x%08x, Protected: %d, Hooked: %d, " 880 "Unpack Protected: %d, Main Module: %d Path: \"%s\"\n",
886 NLOG(
" VAD tree:\n");
891 NLOG(
" VAS monitor:\n");
910 while (list != &gWinProcesses)
915 if (NULL != ProcessName && 0 != strcasecmp(ProcessName, pProc->
Name))
936 LOG(
"Mitigation Flags are not available! 0x%08x 0x%08x\n",
944 while (list != &gWinProcesses)
950 static const PCHAR flagsText[] =
952 "ControlFlowGuardEnabled",
953 "ControlFlowGuardExportSuppressionEnabled",
954 "ControlFlowGuardStrict",
955 "DisallowStrippedImages",
956 "ForceRelocateImages",
957 "HighEntropyASLREnabled",
958 "StackRandomizationDisabled",
959 "ExtensionPointDisable",
960 "DisableDynamicCode",
961 "DisableDynamicCodeAllowOptOut",
962 "DisableDynamicCodeAllowRemoteDowngrade",
963 "AuditDisableDynamicCode",
964 "DisallowWin32kSystemCalls",
965 "AuditDisallowWin32kSystemCalls",
966 "EnableFilteredWin32kAPIs",
967 "AuditFilteredWin32kAPIs",
968 "DisableNonSystemFonts",
969 "AuditNonSystemFontLoading",
970 "PreferSystem32Images",
971 "ProhibitRemoteImageMap",
972 "AuditProhibitRemoteImageMap",
973 "ProhibitLowILImageMap",
974 "AuditProhibitLowILImageMap",
975 "SignatureMitigationOptIn",
976 "AuditBlockNonMicrosoftBinaries",
977 "AuditBlockNonMicrosoftBinariesAllowStore",
978 "LoaderIntegrityContinuityEnabled",
979 "AuditLoaderIntegrityContinuity",
980 "EnableModuleTamperingProtection",
981 "EnableModuleTamperingProtectionNoInherit",
983 static const PCHAR flags2Text[] =
985 "EnableExportAddressFilter",
986 "AuditExportAddressFilter",
987 "EnableExportAddressFilterPlus",
988 "AuditExportAddressFilterPlus",
989 "EnableRopStackPivot",
990 "AuditRopStackPivot",
991 "EnableRopCallerCheck",
992 "AuditRopCallerCheck",
995 "EnableImportAddressFilter",
996 "AuditImportAddressFilter",
1007 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1017 ERROR(
"[ERROR] IntKernVirtMemRead failed: 0x%08x\n", status);
1022 NLOG(
"+ Mitigation Flags: 0x%08x\n", flags.
Flags);
1023 for (
DWORD i = 0; i < 32; i++)
1025 if (0 == (flags.
Flags & (1 << i)))
1032 NLOG(
"\t Bit %02d is set -> UNKNOWN\n", i);
1036 NLOG(
"\t Bit %02d is set -> %s\n", i, flagsText[i]);
1040 NLOG(
"+ Mitigation Flags 2: 0x%08x\n", flags2.
Flags);
1041 for (
DWORD i = 0; i < 32; i++)
1043 if (0 == (flags2.
Flags & (1 << i)))
1050 NLOG(
"\t Bit %02d is set -> UNKNOWN\n", i);
1054 NLOG(
"\t Bit %02d is set -> %s\n", i, flags2Text[i]);
1082 static DWORD sizeofNeededEprocess = 0;
1099 if (0 == sizeofNeededEprocess)
1103 if (sizeofNeededEprocess < gWinGuest->OsSpecificFields.Km.Process[field])
1125 sizeofNeededEprocess--;
1130 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.
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.
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.
#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.
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)
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.
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.
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).
enum _WIN_KM_FIELD_PROCESS WIN_KM_FIELD_PROCESS
Indexes in the WIN_OPAQUE_FIELDS.Km.Process array, containing offsets inside the _EPROCESS structure...
#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.
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.
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)
#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)
struct _WIN_OPAQUE_FIELDS::@207 Km
Kernel mode information.
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.