19 #define LIX_MM_PROT_MASK BIT(63) 90 #define for_next_task(_task, _var_name) list_for_next(_task, gLixTasks, LIX_TASK_OBJECT, _var_name) 95 #define for_each_task(_var_name) list_for_each(gLixTasks, LIX_TASK_OBJECT, _var_name) 100 #define for_each_protected_task(_var_name) list_for_each_link(gLixProtectedTasks, LIX_TASK_OBJECT, \ 101 ExploitProtProcLink, _var_name) 106 #define for_each_task_to_protect(_var_name) list_for_each(gLixTasksToProtect, LIX_PROTECTED_PROCESS, _var_name) 117 #define for_each_path(_var_name) list_for_each(gLixTaskPaths, LIX_TASK_PATH, _var_name) 139 for (i = len - 1; i && (path[i] !=
'/'); i--);
141 return path + i + !!(path[i] ==
'/');
157 for (; i && path[i] ==
'/'; i--)
218 if (pPath->DentryGva == DentryGva)
229 ERROR(
"[ERROR] IntLixFileGetPath failed for %llx: %08x\n", FileGva, status);
240 ERROR(
"[ERROR] IntReadString failed for %llx: %08x\n", PathGva, status);
262 if (NULL == pPath->
Path)
268 memcpy(pPath->
Path, path, len + 1ull);
301 ERROR(
"[ERROR] IntLixFileGetDentry failed for file %llx: %08x\n", FileGva, status);
380 if (Task->KernelMode)
385 else if (Task->IsThread)
391 return (gLixTaskLogLevel.
Execs || (Protected && gLixTaskLogLevel.
ProtExecs));
395 return (gLixTaskLogLevel.
Forks || (Protected && gLixTaskLogLevel.
ProtForks));
419 if (NULL == InitTask)
432 startGva < gLixGuest->Layout.DataEnd;
441 ERROR(
"[ERROR] IntVirtMemMap failed for 0x%016llx 0x%08x\n", startGva, status);
447 QWORD parent, mm, signal;
457 ERROR(
"[ERROR] IntVirtMemFetchQword failed: 0x%08x\n", status);
463 parent = *(
QWORD *)(p + offset +
LIX_FIELD(TaskStruct, RealParent));
477 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed: 0x%08x\n", status);
497 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for 0x%016llx: 0x%08x\n",
518 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed: 0x%08x\n", status);
536 ERROR(
"[ERROR] Failed reading process name @ 0x%016llx: 0x%08x\n",
537 ts +
LIX_FIELD(TaskStruct, Comm), status);
543 if (0 != memcmp(comm,
"swapper", 7))
548 TRACE(
"[LIXTASK] Found init_task @ 0x%016llx with name %s\n", ts, comm);
596 ERROR(
"[ERROR] IntVirtMemMap failed for %llx: %08x\n",
gTaskMapped, status);
632 DWORD remaining = Size;
638 memcpy(Buffer,
gTaskPtr1 + Offset, toRead);
650 ERROR(
"[ERROR] IntVirtMemMap failed for %llx: %08x\n", nextPage, status);
660 memcpy(Buffer,
gTaskPtr1 + Offset, Size);
722 if (Task->KernelMode)
732 ERROR(
"[ERROR] Fetching mm failed in task 0x%016llx: 0x%08x\n", Task->Gva, status);
748 if (Parent && Parent->MmGva == mmGva)
750 Task->Cr3 = Parent->Cr3;
758 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for GVA 0x%016llx: 0x%08x\n",
759 mmGva +
LIX_FIELD(MmStruct, Pgd), status);
760 goto _cleanup_and_exit;
765 ERROR(
"[ERROR] The PGD 0x%016llx @ 0x%016llx (offset %x) is not a valid one!\n",
770 goto _cleanup_and_exit;
776 ERROR(
"[ERROR] Failed translating PGD 0x%016llx: 0x%08x\n", pgd, status);
812 if (TaskStruct == NULL)
825 ERROR(
"[ERROR] IntGsRead failed for cpu %d: 0x%08x.\n", CpuNumber, status);
831 WARNING(
"[WARNING] 'gs' for cpu %d is not in kernel mode: %llx\n", CpuNumber, gsBase);
838 ERROR(
"[ERROR] IntKernVirtMemPatchQword failed for gva 0x%llx with status: 0x%08x\n",
845 ERROR(
"[ERROR] Current task 0x%016llx is not valid!\n", current);
849 *TaskStruct = current;
961 if (pTask->Cr3 == Cr3)
986 if (pTask->MmGva == MmGva)
1012 if (pTask->MmGva == MmGva)
1038 if (pTask->Gva == TaskStruct)
1064 if (pTask->Pid == Pid)
1121 QWORD trapFrameGva, kmStack;
1126 ERROR(
"[ERROR] Failed to read km stack pointer for task %s (%d 0x%llx). Status: 0x%08x\n",
1127 Task->Comm, Task->Pid, Task->Gva, status);
1131 trapFrameGva = kmStack +
LIX_FIELD(Info, ThreadSize) -
sizeof(*TrapFrame);
1133 memzero(TrapFrame,
sizeof(*TrapFrame));
1159 if ((pProt->NamePattern && Task->Path &&
IntMatchPatternUtf8(pProt->NamePattern, Task->Path->Name, 0)) ||
1172 _In_ const void *Name,
1187 WARNING(
"[WARNING] Unsupported string encoding: %d\n", Encoding);
1195 pProcess->Protection.Current = pProcess->Protection.Original & ~(Options->ForceOff);
1196 pProcess->Protection.Beta = Options->ForceBeta;
1197 pProcess->Protection.Feedback = Options->ForceFeedback;
1199 TRACE(
"[CAMI] Protected process info updated. Original : 0x%llx, Current : 0x%llx, " 1200 "Beta : 0x%llx, Feedback : 0x%llx", pProcess->Protection.Original, pProcess->Protection.Current,
1201 pProcess->Protection.Beta, pProcess->Protection.Feedback);
1233 ERROR(
"[ERROR] IntIcFlushVaSpace failed: 0x%08x\n", status);
1241 CRITICAL(
"[ERROR] IntKernVirtMemFetchQword failed for mm %llx: %08x\n", Task->MmGva, status);
1251 ERROR(
"[ERROR] IntKernVirtMemPatchQword failed for mm %llx: %08x\n", Task->MmGva, status);
1255 if (Task->HookObject)
1260 ERROR(
"[ERROR] IntHookObjectDestroy failed: %08x", status);
1297 ERROR(
"[ERROR] Requesting to protect process '%s' (%d, %llx, %llx)but it has no CR3 (mm 0x%016llx)!\n",
1298 Task->ProcName, Task->Pid, Task->Gva, Task->Cr3, Task->MmGva);
1302 if (Task->StaticDetected)
1306 DWORD mmUsers = 0, mmCount = 0;
1311 ERROR(
"[ERROR] Failed getting mm_users: %08x\n", status);
1318 ERROR(
"[ERROR] Failed getting mm_count: %08x\n", status);
1322 if (0 == mmUsers || 0 == mmCount)
1324 WARNING(
"[WARNING] Process %s (%d, %llx, %llx) has a dying mm @ %llx: (%d, %d)!\n",
1325 Task->Comm, Task->Pid, Task->Gva, Task->Cr3, Task->MmGva, mmUsers, mmCount);
1335 ERROR(
"[ERROR] IntHookObjectCreate failed: %08x\n", status);
1342 ERROR(
"[ERROR] IntLixMmPopulateVmas failed: 0x%08x\n", status);
1343 goto _free_and_exit;
1351 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for mm %llx: %08x\n", Task->MmGva, status);
1352 goto _free_and_exit;
1361 ERROR(
"[ERROR] IntKernVirtMemPatchQword failed for mm %llx: %08x\n", Task->MmGva, status);
1362 goto _free_and_exit;
1396 if (Task->Interpreter)
1417 Task->Context = pProt->
Context;
1421 Task->Protection.Mask = 0;
1425 Task->RootProtectionMask = Task->Protection.Mask;
1432 Task->Protection.Mask = Parent->RootProtectionMask;
1433 Task->Protection.Beta = Parent->Protection.Beta;
1434 Task->Protection.Feedback = Parent->Protection.Feedback;
1436 Task->RootProtectionMask = Parent->RootProtectionMask;
1437 Task->Context = Parent->Context;
1440 if (0 == Task->Protection.Mask)
1445 sameCr3 = Parent && (Task->Cr3 == Parent->Cr3);
1459 ERROR(
"[ERROR] Process '%s' (%d, %llx, %llx) will not be exploit-protected: %08x!\n",
1460 Task->ProcName, Task->Pid, Task->Gva, Task->Cr3, status);
1469 if (!sameCr3 && (Task->Protection.Mask == 0))
1471 ERROR(
"[ERROR] Task %s, 0x%016llx failed to activate any protection!\n", Task->Comm, Task->Gva);
1473 Task->Protected =
FALSE;
1485 TRACE(
"[PROC] Activated protection %llx for '%s' (%d, %llx, %llx)\n",
1486 Task->Protection.Mask, Task->ProcName, Task->Pid, Task->Gva, Task->Cr3);
1489 Task->Protected =
TRUE;
1507 if (!Task->Protected)
1515 WARNING(
"[WARNING] Process '%s' (%d, %llx, %llx) failed to deactivate protection: %08x\n",
1516 Task->ProcName, Task->Pid, Task->Gva, Task->Cr3, status);
1521 LOG(
"[PROC] Deactivated protection for %s '%s' (%d, %llx, %llx)!\n",
1522 Task->IsThread ?
"thread" :
"process", Task->ProcName,
1523 Task->Pid, Task->Gva, Task->Cr3);
1526 Task->Protection.Mask = 0;
1527 Task->RootProtectionMask = 0;
1529 Task->Protected =
FALSE;
1550 QWORD vmaStart, vmaEnd, iter, file;
1551 DWORD argc, curLength;
1552 BYTE *pMapping = NULL;
1557 ERROR(
"[ERROR] IntVirtMemMap failed for %llx: 0x%08x\n", BinprmGva, status);
1573 ERROR(
"[ERROR] IntVirtMemMap failed for %llx: 0x%08x\n", file, status);
1582 if (vmaStart >= vmaEnd)
1584 ERROR(
"[ERROR] Start of vma_struct %llx is bigger or equal that the end %llx!\n", vmaStart, vmaEnd);
1590 ERROR(
"[ERROR] Argpage VMA is to big: 0x%llu. Cmdline will not be fetched\n", vmaEnd - vmaStart);
1595 for (iter = vmaStart;
1599 if ((iter >= vmaEnd) || NULL == pMapping)
1601 ERROR(
"[ERROR] Could not read cmdline. Not a single page from VMA 0x%llx to 0x%llx is present!\n",
1607 if (NULL == Process->CmdLine)
1617 while ((0 == curLength) && (parsed <
PAGE_SIZE) && (0 == pMapping[parsed]))
1624 if (0 == pMapping[parsed])
1631 Process->CmdLine[curLength] =
' ';
1635 Process->CmdLine[curLength] = pMapping[parsed];
1652 WARNING(
"[WARNING] Reached end of vma, but there are %d more args to be read!\n", argc);
1659 ERROR(
"[ERROR] IntVirtMemMap failed: %08x\n", status);
1664 Process->CmdLine[curLength] = 0;
1665 Process->CmdLineLength = curLength + 1;
1685 Task->ProcName = Task->Path->Path;
1686 Task->ProcNameLength = (
DWORD)Task->Path->PathLength;
1690 Task->ProcName = Task->Comm;
1691 Task->ProcNameLength = strlen(Task->Comm);
1713 ERROR(
"[ERROR] IntLixFileGetDentry failed for %llx: %08x\n", FileGva, status);
1717 if (!
IS_ERR(DPathGva) && DPathGva)
1722 if (NULL == Task->Path)
1750 QWORD pathGva, interpGva;
1761 UpdatedTask->ActualParent = OriginalTask->Parent;
1762 UpdatedTask->AgentTag = OriginalTask->AgentTag;
1763 UpdatedTask->Context = OriginalTask->Context;
1764 UpdatedTask->CreationTime = OriginalTask->CreationTime;
1765 UpdatedTask->Gva = OriginalTask->Gva;
1766 UpdatedTask->IsThread =
FALSE;
1767 UpdatedTask->KernelMode =
FALSE;
1768 UpdatedTask->Parent = OriginalTask->Parent;
1769 UpdatedTask->RealParent = OriginalTask->RealParent;
1770 UpdatedTask->Tgid = OriginalTask->Tgid;
1771 UpdatedTask->Pid = OriginalTask->Pid;
1773 memcpy(UpdatedTask->Comm, OriginalTask->Comm,
sizeof(UpdatedTask->Comm));
1777 UpdatedTask->ReExecToSelf =
FALSE;
1782 ERROR(
"[ERROR] IntVirtMemMap failed for GVA 0x%016llx: 0x%08x\n", BinprmGva, status);
1783 goto _cleanup_and_exit;
1789 ERROR(
"[ERROR] _IntLixTaskStartMap failed for task %llx: 0x%08x\n", UpdatedTask->Gva, status);
1790 goto _cleanup_and_exit;
1799 ERROR(
"[ERROR] _IntLixTaskRead failed for %llx: %08x\n",
1800 UpdatedTask->Gva +
LIX_FIELD(TaskStruct, InExecve), status);
1802 else if (0 == (in &
BIT(
LIX_FIELD(TaskStruct, InExecveBit))))
1804 ERROR(
"[ERROR][CRITICAL] in_execve is not in fact set: 0x%02x\n", in);
1811 ERROR(
"[ERROR] IntLixTaskFetchMm failed for %s: 0x%08x. The process cannot be protected!\n",
1812 UpdatedTask->ProcName, status);
1820 if (interpGva && interpGva != pathGva)
1822 status =
IntReadString(interpGva, 2,
FALSE, &UpdatedTask->Interpreter, &UpdatedTask->InterpLength);
1825 UpdatedTask->Interpreter = NULL;
1826 UpdatedTask->InterpLength = 0;
1834 ERROR(
"[ERROR] Failed getting the PID from task_struct %llx: %08x\n",
1835 UpdatedTask->Gva +
LIX_FIELD(TaskStruct, Pid), status);
1837 else if (exitSignal < 0)
1845 ERROR(
"[ERROR] Failed getting the group_leader from task_struct %llx: %08x\n",
1846 UpdatedTask->Gva +
LIX_FIELD(TaskStruct, GroupLeader), status);
1851 if (NULL == pGroupLeader)
1856 ERROR(
"[ERROR] IntKernVirtMemFetchDword failed for %llx: %08x\n",
1857 groupLeader +
LIX_FIELD(TaskStruct, Pid), status);
1862 pid = pGroupLeader->
Pid;
1865 if (UpdatedTask->Pid != pid)
1867 TRACE(
"[INFO] Process '%s' changes PID from %d to %d\n", UpdatedTask->ProcName, UpdatedTask->Pid, pid);
1869 UpdatedTask->Pid = pid;
1874 if (OriginalTask->ExeFileDentry == UpdatedTask->ExeFileDentry)
1876 UpdatedTask->ReExecToSelf =
TRUE;
1879 if ((!UpdatedTask->ReExecToSelf) && OriginalTask->Interpreter && UpdatedTask->Interpreter)
1881 if (OriginalTask->InterpLength == UpdatedTask->InterpLength &&
1882 0 == strcmp(OriginalTask->Interpreter, UpdatedTask->Interpreter))
1884 UpdatedTask->ReExecToSelf =
TRUE;
1897 ERROR(
"[ERROR] IntLixCredAdd failed for %s (%d 0x%llx). Status: 0x%08x\n",
1898 UpdatedTask->Comm, UpdatedTask->Pid, UpdatedTask->Gva, status);
1899 UpdatedTask->Creds = NULL;
1940 if (Created && Task->ReExecToSelf)
1946 memzero(pProcEvent,
sizeof(*pProcEvent));
1948 pProcEvent->
Created = Created;
1949 pProcEvent->
Protected = Task->Protected != 0;
1950 pProcEvent->
Crashed = Crashed;
1953 if (!StaticDetected)
1977 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
1999 if (!Task->AgentTag)
2005 memzero(pAgentEvent,
sizeof(*pAgentEvent));
2012 pAgentEvent->
AgentTag = Task->AgentTag;
2018 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
2048 ERROR(
"[ERROR] IntLixTaskGetTrapFrame failed: %08x\n", status);
2052 if (NULL != StackBase || NULL != StackLimit)
2057 ERROR(
"[ERROR] Failed to find stack limits for process %s (%d 0x%llx), rsp: 0x%llx. Status:0x%08x\n",
2058 Task->Comm, Task->Pid, Task->Gva, trapFrame.
Rsp, status);
2062 if (NULL != StackBase)
2067 if (NULL != StackLimit)
2069 *StackLimit = limit;
2073 if (NULL != StackPointer)
2075 *StackPointer = trapFrame.
Rsp;
2115 ERROR(
"[ERROR] Failed getting the flags in task 0x%016llx: 0x%08x\n", TaskStruct, status);
2121 TRACE(
"[INFO] Task with 0x%llx is dying while initializing (static: %d)... Will ignore.\n",
2122 TaskStruct, StaticDetected);
2136 pTask->
Gva = TaskStruct;
2141 ERROR(
"[ERROR] Failed getting the 'PID' in task 0x%016llx: 0x%08x\n", pTask->
Gva, status);
2142 goto _free_and_exit;
2145 if (!StaticDetected)
2153 ERROR(
"[ERROR] [CRITICAL] There is already an existing task with PID %d\n", pTask->
Pid);
2155 LOG(
"[ERROR] %s%s %s (%d/%d, %16llx)]\n",
2156 pExistingTask->
IsThread ?
"Thread" :
"Process",
2159 pExistingTask->
Pid, pExistingTask->
Tgid, pExistingTask->
Gva);
2166 ERROR(
"[ERROR] Failed getting the 'tgid' in task 0x%016llx: 0x%08x\n", pTask->
Gva, status);
2167 goto _free_and_exit;
2174 ERROR(
"[ERROR] Failed reading 'comm' in task 0x%016llx: 0x%08x\n", pTask->
Gva, status);
2175 goto _free_and_exit;
2198 (!pTask->
IsThread && RealParent->Pid == 1))
2207 pActualParent = RealParent;
2211 if (NULL == pActualParent)
2213 WARNING(
"[WARNING] Task with TGID %d is dead\n", pTask->
Tgid);
2214 pActualParent = RealParent;
2220 pTask->
Parent = Parent->Gva;
2224 QWORD time[2] = {0};
2229 ERROR(
"[ERROR] Failed getting the start time in task 0x%016llx: 0x%08x\n", pTask->
Gva, status);
2230 goto _free_and_exit;
2243 ERROR(
"[ERROR] Failed getting the start time in task 0x%016llx: 0x%08x\n", pTask->
Gva, status);
2244 goto _free_and_exit;
2256 ERROR(
"[ERROR] IntLixTaskFetchMm failed: 0x%08x. This task (%s) cannot be protected!\n",
2257 status, pTask->
Comm);
2275 ERROR(
"[ERROR] IntKernVirtMemFetchQword failed for %llx: %08x\n",
2277 goto _initialize_and_prot;
2283 ERROR(
"[ERROR] IntLixFileGetDentry failed for %llx: %08x\n", file, status);
2284 goto _initialize_and_prot;
2290 _initialize_and_prot:
2307 ERROR(
"[ERROR] IntLixTaskActivateProtection failed for %s (%llx): 0x%08x\n", pTask->
Comm, pTask->
Gva, status);
2324 ERROR(
"[ERROR] IntLixCredAdd failed for task %s (%d 0x%llx) with status: 0x%08x!. Creds gva: 0x%llx\n",
2325 pTask->
Comm, pTask->
Pid, pTask->
Gva, status, creds);
2330 ERROR(
"[ERROR] _IntLixTaskRead failed for task %s (%d 0x%llx): 0x%08x\n",
2331 pTask->
Comm, pTask->
Pid, pTask->
Gva, status);
2339 ERROR(
"[ERROR] Failed to get user mode stack for process %s (%d, 0x%llx). Status: 0x%08x\n",
2340 pTask->
Comm, pTask->
Pid, pTask->
Gva, status);
2346 pTask->
Dpi.
StolenTokens = RealParent->Dpi.StolenTokens || Parent->Dpi.StolenTokens;
2352 LOG(
"[%s]%s %s (%s), (%d/%d, %llx, %llx) [from %s%s %s (%d, %16llx)]\n",
2353 pTask->
Exec ?
"EXEC" :
"FORK",
2359 pActualParent->
IsThread ?
"Thread" :
"Process",
2362 pActualParent->
Pid, pActualParent->
Gva);
2366 LOG(
"[THREAD]%s %s, (%d/%d, %llx, %llx)\n",
2380 if (StaticDetected && pTask->
Exec)
2417 if (Task->Protected)
2426 if (NULL != Task->Interpreter)
2431 if (NULL != Task->CmdLine)
2451 char specialChar =
'?';
2459 Task->Gva +
LIX_FIELD(TaskStruct, Comm) + 14,
2465 ERROR(
"[ERROR] IntVirtMemSafeWrite failed for task %llx: 0x%08x\n", Task->Gva, status);
2486 if (Task->Protected)
2489 wasProtected =
TRUE;
2492 signal = ExitCode & 0x7f;
2494 if ((ExitCode & 0x80) ||
2510 WARNING(
"[WARNING] Task %s (%d, %llx, %llx) was marked to be killed, but the signal it received is %d",
2511 Task->ProcName, Task->Pid, Task->Cr3, Task->Gva, signal);
2528 if (!Task->IsThread && !Task->KernelMode && Task->Cr3 != 0)
2534 ERROR(
"[ERROR] IntIcFlushVaSpace failed: 0x%08x\n", status);
2546 LOG(
"[EXIT] %s %s (%d, %llx, %llx), crashed: %d, signal: %d\n",
2547 Task->IsThread ?
"Thread" :
"Process", Task->ProcName, Task->Pid,
2548 Task->Cr3, Task->Gva, crashed, signal);
2551 if (!Task->IsThread)
2583 ERROR(
"[ERROR] We do not have any known DPI flag set -> Flags:0x%x\n", Flags);
2610 memzero(pEvent,
sizeof(*pEvent));
2636 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
2656 if (Task->Dpi.IsPivoted)
2661 if (Task->Dpi.StolenTokens)
2698 ERROR(
"[ERROR] IntLixValidateProcessCreationRights called with object type %d!\n", ObjectType);
2703 if (ChildTask->ReExecToSelf)
2709 if (ParentTask->KernelMode)
2718 if (originator.
PcType == 0)
2730 ERROR(
"[ERROR] IntExceptUserGetOriginator failed with status: 0x%08x.\n", status);
2739 ERROR(
"[ERROR] IntExceptGetVictimProcessCreation failed with status: 0x%08x.\n", status);
2751 LOG(
"[PROCESS CREATION] Process creation blocked. Process `%s` tried to start using process `%s`",
2752 ChildTask->Comm, ParentTask->Comm);
2763 LOG(
"[PROCESS CREATION] Process creation blocked. Process `%s` tried to start with DPI using process `%s`",
2764 ChildTask->Comm, ParentTask->Comm);
2797 if (NULL == Task || Task->KernelMode)
2807 if (NULL == IsPivoted)
2812 if (Task->UserStack.Valid)
2822 if (!Task->IsThread)
2826 WARNING(
"[WARNING] Parent task %s (%d 0x%llx) is not a thread and doesn't have a valid mm pointer!\n",
2827 Task->Comm, Task->Pid, Task->Gva);
2829 goto _check_altstack;
2835 ERROR(
"[ERROR] Failed to read start_stack from mm. Task %s (%d 0x%llx), MmGva 0x%llx, status: 0x%08x\n",
2836 Task->Comm, Task->Pid, Task->Gva, Task->MmGva, status);
2843 ERROR(
"[ERROR] Failed to find VAD for task->mm.start_stack(0x%llx) for process %s (%d 0x%llx). " 2844 "Status: 0x%08x\\n", base, Task->Comm, Task->Pid, Task->Gva, status);
2859 ERROR(
"[ERROR] Failed to read alt stack. Task %s (%d 0x%llx), status: 0x%08x\n",
2860 Task->Comm, Task->Pid, Task->Gva, status);
2870 ERROR(
"[ERROR] Failed to find alt stack (0x%llx) VAD for process %s (%d 0x%llx). Status: 0x%08x\n",
2871 base, Task->Comm, Task->Pid, Task->Gva, status);
2905 if (ParentTask->KernelMode)
2913 ERROR(
"[ERROR] Failed to get user mode stack pointer for parent task %s (%d 0x%llx). Status: 0x%08x\n",
2914 ParentTask->Comm, ParentTask->Pid, ParentTask->Gva, status);
2921 ERROR(
"[ERROR] IntLixTaskIsStackPivoted failed for stack ptr 0x%llx with status 0x%08x.", stackPointer, status);
2940 QWORD binprm, dPathResult;
2946 QWORD oldProtectionMask;
2947 static DWORD taskCount = 0;
2952 if (NULL == pOldTask)
2954 ERROR(
"[ERROR] No task on for exec!\n");
2981 ERROR(
"[ERROR] Failed updating process contents from the linux_binprm @ %16llx: 0x%08x\n",
2996 ERROR(
"[ERROR] We couldn't get path for process, the comm will be the old one!\n");
3008 TRACE(
"[INIT] Init process re-executes itself\n");
3027 goto _action_not_allowed;
3036 _action_not_allowed:
3042 ERROR(
"[ERROR] IntDetSetReturnValue failed: %08x\n", status);
3059 ERROR(
"[ERROR] IntLixTaskActivateProtection failed for %s: 0x%08x\n", pTask->
Comm, status);
3070 LOG(
"[EXEC] %s %s (%d, %llx, %llx) exec to %s (interp: %s)\n",
3076 LOG(
"[EXEC] %s %s (%d, %llx, %llx) exec to %s\n",
3094 if ((oldLen != newLen) || (0 != memcmp(pOldTask->
Comm, pTask->
Comm, oldLen)))
3125 ERROR(
"[ERROR] IntLixVdsoDynamicProtect failed with status: 0x%08x.", status);
3134 ERROR(
"[ERROR] IntDetSetReturnValue failed: %08x\n", status);
3158 ERROR(
"[ERROR] IntLixTaskAdd failed for %llx on cpu %d: 0x%08x\n",
3187 memzero(pInjEvent,
sizeof(*pInjEvent));
3213 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%08x\n", status);
3245 pSource = pVictim = NULL;
3250 ERROR(
"[ERROR] IntLixTaskGetCurrentStruct failed: 0x%08x\n", status);
3256 if ((Pid && pProc->Pid == (
DWORD)Victim) || (!Pid && pProc->Gva == Victim))
3261 if (pProc->Gva == currentTask)
3266 if ((NULL != pVictim) && (NULL != pSource))
3272 if (NULL == pVictim || NULL == pSource)
3280 LOG(
"[PTRACE] Injection from %s (%d, %llx) into %s (%d, %llx)\n",
3292 memzero(&originator,
sizeof(originator));
3293 memzero(&victim,
sizeof(victim));
3301 ERROR(
"[ERROR] Failed getting originator: 0x%08x\n", status);
3302 goto _send_notification;
3312 ERROR(
"[ERROR] Failed getting modified zone: 0x%08x\n", status);
3313 goto _send_notification;
3323 LOG(
"[INJECTION] Block injection from process %s (%d) into process %s (%d)\n",
3330 LOG(
"[INJECTION] Allow injection from process %s into process %s\n",
3370 ERROR(
"[ERROR] IntLixTaskHandleInjection failed: %08x\n", status);
3371 goto _emulate_and_leave;
3378 ERROR(
"[ERROR] IntDetoursGstSetReturnValue failed: 0x%08x\n", status);
3411 ERROR(
"[ERROR] IntLixTaskHandleInjection failed: %08x\n", status);
3412 goto _emulate_and_leave;
3420 ERROR(
"[ERROR] IntLixTaskHandleSetRegs failed: %08x\n", status);
3421 goto _emulate_and_leave;
3426 WARNING(
"[WARNING] The request argument (%llx) for 'ptrace' is allowed ...\n", request);
3428 goto _emulate_and_leave;
3436 ERROR(
"[ERROR] IntDetoursGstSetReturnValue failed: 0x%08x\n", status);
3460 TRACE(
"[INFO] Task dying without being in the list... Ignore it!");
3466 LOG(
"[ERROR] Init task is exiting, something isn't right...\n");
3496 QWORD currentThread;
3498 QWORD signalListHead = 0;
3507 ERROR(
"[ERROR] Failed reading the signal struct: 0x%08x\n", status);
3513 ERROR(
"[ERROR] task->signal value (0x%llx) does not point to a valid kernel memory location.", signal);
3520 ERROR(
"[ERROR] Failed reading from the signal struct: 0x%08x\n", status);
3532 else if (nrThreads < 0)
3534 ERROR(
"[ERROR] Negative number of threads: %d\n", nrThreads);
3539 signalListHead = signal +
LIX_FIELD(Ungrouped, SignalListHead);
3544 ERROR(
"[ERROR] Failed getting the first task from signal 0x%016llx\n", signalListHead);
3548 currentThread -=
LIX_FIELD(TaskStruct, ThreadNode);
3554 ERROR(
"[ERROR] Failed getting the next task from 0x%016llx\n",
3555 currentThread +
LIX_FIELD(TaskStruct, ThreadNode));
3563 ERROR(
"[ERROR] Thread 0x%llx does not point to a valid kernel memory location.\n", currentThread);
3567 currentThread -=
LIX_FIELD(TaskStruct, ThreadNode);
3569 status = Callback(currentThread, Aux);
3584 ERROR(
"[ERROR] Failed getting the next task from 0x%016llx\n",
3585 currentThread +
LIX_FIELD(TaskStruct, ThreadNode));
3594 ERROR(
"[ERROR] We didn't processed enough threads. Remaining: %d\n", nrThreads);
3597 else if (nrThreads < 0)
3599 ERROR(
"[ERROR] We processed more threads. Over: %d\n", nrThreads);
3628 QWORD currentThread;
3629 QWORD signal, threadListHead;
3638 ERROR(
"[ERROR] Failed reading the signal struct: 0x%08x\n", status);
3644 ERROR(
"[ERROR] task->signal value (0x%llx) does not point to a valid kernel memory location.", signal);
3651 ERROR(
"[ERROR] Failed reading from the signal struct: 0x%08x\n", status);
3663 else if (nrThreads < 0)
3665 ERROR(
"[ERROR] Negative number of threads: %d\n", nrThreads);
3670 threadListHead = TaskStructGva +
LIX_FIELD(TaskStruct, ThreadGroup);
3675 ERROR(
"[ERROR] Failed getting the first task from signal 0x%016llx\n", threadListHead);
3683 ERROR(
"[ERROR] Thread 0x%llx does not point to a valid kernel memory location.\n", currentThread);
3687 currentThread -=
LIX_FIELD(TaskStruct, ThreadGroup);
3689 status = Callback(currentThread, Aux);
3704 ERROR(
"[ERROR] Failed getting the next task from 0x%016llx\n",
3705 currentThread +
LIX_FIELD(TaskStruct, ThreadGroup));
3714 ERROR(
"[ERROR] We didn't processed enough threads. Remaining: %d\n", nrThreads);
3717 else if (nrThreads < 0)
3719 ERROR(
"[ERROR] We processed more threads. Over: %d\n", nrThreads);
3745 if (0 !=
LIX_FIELD(TaskStruct, ThreadGroup))
3749 else if (0 !=
LIX_FIELD(TaskStruct, ThreadNode))
3777 QWORD initGva, currentTask;
3783 ERROR(
"[ERROR] Failed finding the init_task: 0x%08x\n", status);
3790 status = Callback(initGva, Aux);
3809 ERROR(
"[ERROR] Failed getting the first task from 0x%016llx\n", initGva +
LIX_FIELD(TaskStruct, Tasks));
3813 currentTask -=
LIX_FIELD(TaskStruct, Tasks);
3819 ERROR(
"[ERROR] task_struct 0x%llx does not point to a valid kernel memory location.\n", currentTask);
3823 status = Callback(currentTask, Aux);
3838 ERROR(
"[ERROR] Failed getting the next task from 0x%016llx\n",
3839 currentTask +
LIX_FIELD(TaskStruct, Tasks));
3843 currentTask -=
LIX_FIELD(TaskStruct, Tasks);
3874 if (NULL == pInitTask)
3879 pInitTask->
Gva = TaskGva;
3880 TRACE(
"[LIXTASK] Init task @ 0x%016llx\n", pInitTask->
Gva);
3883 pInitTask->
Parent = TaskGva;
3886 pInitTask->
Path = NULL;
3897 ERROR(
"[ERROR] Failed getting PID of the init process @0x%016llx: 0x%08x\n",
3898 pInitTask->
Gva, status);
3902 sizeof(pInitTask->
Comm),
3908 ERROR(
"[ERROR] Failed reading init process name @ 0x%016llx: 0x%08x\n",
3910 pInitTask->
Comm[0] = 0;
3914 pInitTask->
Comm[
sizeof(pInitTask->
Comm) - 1] = 0;
3918 if ((0 ==
LIX_FIELD(TaskStruct, ThreadGroup)) && (0 ==
LIX_FIELD(TaskStruct, ThreadNode)))
3920 QWORD signal, flink;
3925 ERROR(
"[ERROR] Failed reading the init's signal struct: 0x%08x\n", status);
3932 ERROR(
"[ERROR] Failed reading from init's signal struct: 0x%08x\n", status);
3939 ERROR(
"[ERROR] Signal's struct is not good: 0x%016llx 0x%016llx 0x%016llx\n", flink, signal, TaskGva);
3986 ERROR(
"[ERROR] IntLixTaskCreateInitTask failed: 0x%08x\n", status);
3992 QWORD parentTs, realParentTs;
3995 parentTs = realParentTs = 0;
4000 ERROR(
"[ERROR] _IntLixTaskStartMap failed for %llx: %08x\n", TaskGva, status);
4007 ERROR(
"[ERROR] Failed getting the real parent: %08x\n", status);
4014 ERROR(
"[ERROR] Failed getting the parent: %08x\n", status);
4019 if (NULL == pParent)
4021 WARNING(
"[WARNING] IntLixTaskFindByGva failed for parent 0x%016llx\n", parentTs);
4024 if (NULL == pParent)
4026 ERROR(
"[ERROR] IntLixTaskFindByPid failed for PID 1!\n");
4035 if (parentTs == realParentTs)
4037 pRealParent = pParent;
4043 if (NULL == pRealParent)
4045 WARNING(
"[WARNING] IntLixTaskFindByGva failed for real parent 0x%016llx\n", realParentTs);
4046 pRealParent = pParent;
4054 status =
IntLixTaskCreate(pParent, pRealParent, TaskGva, StaticDetected != 0, NULL);
4057 ERROR(
"[ERROR] IntLixTaskCreate failed: 0x%08x\n", status);
4088 QWORD oldProtection;
4090 oldProtection = Task->Protection.Mask;
4092 if (NewProtection == oldProtection)
4097 if (0 == NewProtection)
4099 LOG(
"[PROT] Removing %s %s (%llx, %llx, %d) from protection", Task->Exec ?
"exec process" :
"fork process",
4100 Task->Comm, Task->Gva, Task->Cr3, Task->Pid);
4104 Task->Protected =
FALSE;
4109 LOG(
"[PROT] Changing protection flags for `%s` (Pid %d, ts 0x%016llx): 0x%llx -> 0x%llx\n",
4110 Task->Comm, Task->Pid, Task->Gva, oldProtection, NewProtection);
4116 LOG(
"[PROT] PROC_OPT_PROT_EXPLOIT disabled -> enabled for %s (%llx, %d)\n",
4117 Task->Comm, Task->Cr3, Task->Pid);
4124 WARNING(
"[WARNING] Process '%s' (%d, %llx, %llx) will not be exploit-protected: %08x!\n",
4125 Task->ProcName, Task->Pid, Task->Gva, Task->Cr3, status);
4132 LOG(
"[PROT] PROC_OPT_PROT_EXPLOIT enabled -> disabled for %s (%llx, %d)\n",
4133 Task->Comm, Task->Cr3, Task->Pid);
4138 ERROR(
"[ERROR] Process '%s' (%d, %llx, %llx) failed to deactivate protection: %08x\n",
4139 Task->ProcName, Task->Pid, Task->Gva, Task->Cr3, status);
4148 LOG(
"[PROT] PROC_OPT_REMEDIATE %s for process %s, %d\n",
4149 0 != (
PROC_OPT_REMEDIATE & NewProtection) ?
"disabled -> enabled" :
"enabled -> disabled",
4150 Task->Comm, Task->Pid);
4155 LOG(
"[PROCESS] PROC_OPT_KILL_ON_EXPLOIT %s for process %s, %d\n",
4157 Task->Comm, Task->Pid);
4162 LOG(
"[PROCESS] PROC_OPT_PROT_WRITE_MEM %s for process %s, %d\n",
4164 Task->Comm, Task->Pid);
4169 LOG(
"[PROCESS] PROC_OPT_PROT_PTRACE %s for process %s, %d\n",
4171 Task->Comm, Task->Pid);
4176 LOG(
"[PROCESS] PROC_OPT_BETA %s for process %s, %d\n",
4177 0 != (
PROC_OPT_BETA & NewProtection) ?
"disabled -> enabled" :
"enabled -> disabled",
4178 Task->Comm, Task->Pid);
4181 Task->Protected =
TRUE;
4182 Task->Protection.Mask = NewProtection;
4183 Task->RootProtectionMask = NewRootProtection;
4184 Task->Context = Context;
4213 QWORD protMask, childProtMask, protBetaMask, protFeedbackMask;
4216 if (pTask->IsThread)
4221 if (!(ProtProc->NamePattern && pTask->Path &&
4228 protMask = Remove ? 0 : ProtProc->Protection.Current;
4229 context = Remove ? 0 : ProtProc->Context;
4230 protBetaMask = Remove ? 0 : ProtProc->Protection.Beta;
4231 protFeedbackMask = Remove ? 0 : ProtProc->Protection.Feedback;
4233 if (pTask->Context != context)
4235 pTask->Context = context;
4238 pTask->Protection.Beta = protBetaMask;
4239 pTask->Protection.Feedback = protFeedbackMask;
4241 if (pTask->Protection.Mask == protMask)
4249 ERROR(
"[ERROR] IntLixTaskChangeProtectionFlags failed for 0x%016llx (Cr3 0x%016llx): 0x%08x\n",
4250 pTask->Gva, pTask->Cr3, status);
4256 if (pChild->Exec || pChild->ActualParent != pTask->Gva)
4264 pChild->Protection.Beta = 0;
4265 pChild->Protection.Feedback = 0;
4270 childProtMask = pTask->Protection.Mask;
4271 pChild->Protection.Beta = pTask->Protection.Beta;
4272 pChild->Protection.Feedback = pTask->Protection.Feedback;
4274 context = pTask->Context;
4276 if (pTask->Cr3 == pChild->Cr3 || 0 == pChild->Cr3)
4286 ERROR(
"[ERROR] IntLixTaskChangeProtectionFlags failed for 0x%016llx (Cr3 0x%016llx): 0x%08x\n",
4287 pChild->Gva, pChild->Cr3, status);
4298 _In_ const char *ProcessName,
4319 if (NULL == ProcessName)
4324 nameLen = strlen(ProcessName);
4328 ERROR(
"[ERROR] Names longer than 64K are not supported!\n");
4334 if ((pExtProt->NamePattern && 0 == strncasecmp(pExtProt->NamePattern, ProcessName, nameLen + 1)) ||
4335 0 == strncasecmp(pExtProt->CommPattern, ProcessName,
MIN(
LIX_COMM_SIZE, nameLen + 1)))
4337 LOG(
"[PROT] Process %s already protected as %s with %llx... Update the protection to %llx\n",
4338 ProcessName, pExtProt->NamePattern ? pExtProt->NamePattern : pExtProt->CommPattern,
4339 pExtProt->Protection.Original, ProtectionMask);
4341 pExtProt->Protection.Original = ProtectionMask;
4342 pExtProt->Protection.Current = ProtectionMask;
4343 pExtProt->Protection.Beta = 0;
4344 pExtProt->Protection.Feedback = 0;
4346 pExtProt->Context = Context;
4365 ERROR(
"[ERROR] Process '%s' will not be protected as there is not enough memory available\n", ProcessName);
4385 LOG(
"[PROT] Process %s / %s protected with %llx\n",
4394 ERROR(
"[ERROR] IntLixTaskAdjustProtection failed for '%s': %08x\n", pProt->
CommPattern, status);
4403 _In_ const char *ProcessName
4418 if (NULL == ProcessName)
4423 nameLen = strlen(ProcessName);
4427 if (0 == strncasecmp(pExtProt->NamePattern, ProcessName, nameLen + 1))
4429 LOG(
"Remove process %s from protected list!\n", pExtProt->NamePattern);
4444 ERROR(
"[ERROR] IntLixTaskAdjustProtection failed for '%s': %08x\n", pProt->
CommPattern, status);
4480 ERROR(
"[ERROR] IntLixTaskAdjustProtection failed for '%s': %08x\n", pProt->
CommPattern, status);
4502 char *cmd = CommandLine;
4508 if (!pTask->AgentTag)
4513 len = snprintf(cmd, Length,
"%s %d ", pTask->Path ? pTask->Path->Name : pTask->Comm, pTask->Pid);
4517 if ((
int)Length < 0)
4548 if (NULL != pProt->NamePattern)
4578 if (!pProc->IsThread)
4588 LOG(
"We have no processes in the system!\n");
4594 for (
DWORD i = 0; i < Level - 1; i++)
4601 else if (Level >= 1)
4612 if (!Task->IsThread)
4614 NLOG(
"%6d/%-6d: %s %-40s CR3: 0x%016llx, prot: %d/%llx, mm_struct: 0x%016llx, task_struct: 0x%016llx, " 4615 "flags: %08x%s%s, parent: 0x%016llx, real_parent: 0x%016llx\n",
4616 Task->Pid, Task->Tgid,
4617 Task->Exec ?
"EXEC" :
"FORK",
4620 Task->Protected, Task->Protection.Mask,
4624 Task->Interpreter ?
", by interpreter " :
"",
4625 Task->Interpreter ? Task->Interpreter :
"",
4626 Task->Parent, Task->RealParent);
4641 NLOG(
"%6d/%-6d: %-16s / %-16s task_struct: 0x%016llx, prot: %d/%llx, flags: %08x, parent: 0x%016llx, " 4642 "real_parent: 0x%016llx\n",
4643 Task->Pid, Task->Tgid, Task->Comm, newComm, Task->Gva, Task->Protected,
4644 Task->Protection.Mask, flags, Task->Parent, Task->RealParent);
4654 if (!pProc->IsThread && pProc->Parent == Task->Gva)
4658 else if (pProc->IsThread && pProc->Tgid == Task->Pid)
4696 if (pThread->IsThread && pThread->KernelMode)
4704 if (NULL == Thread || !Thread->IsThread || !Thread->KernelMode)
4708 LOG(
"We have no kernel thread in the system!\n");
4714 for (i = 0; i < Level; i++)
4727 NLOG(
"%6d/%-6d : %-16s task_struct: 0x%016llx, prot: %d/%llx, flags: %08x\n",
4728 Thread->Pid, Thread->Tgid, Thread->Comm, Thread->Gva,
4729 Thread->Protected, Thread->Protection.Mask, flags);
4733 if (pThread->Parent == Thread->Gva)
4764 if (!pTask->IsThread)
4766 LOG(
"Process %s (%s), PID: %d, TS 0x%016llx, Mm 0x%016llx, Parent 0x%016llx, RealParent 0x%016llx, " 4767 "Protected: %d/%llx\n", !pTask->Exec ?
"(no exec)" : pTask->Path ? pTask->Path->Path :
"(no path)",
4768 pTask->Comm, pTask->Pid, pTask->Gva, pTask->MmGva,
4769 pTask->Parent, pTask->RealParent,
4770 pTask->Protected, pTask->Protection.Mask);
4776 LOG(
" [%016llx -> %016llx] : %08llx [file @%016llx] @ %016llx Hooked=%d (%c%c%c)\n",
4777 pVma->Start, pVma->End, pVma->Flags, pVma->File, pVma->Gva, pVma->Hook ? 1 : 0,
4778 (pVma->Flags &
VM_EXEC) ?
'X' :
'-',
4779 (pVma->Flags &
VM_WRITE) ?
'W' :
'-',
4780 (pVma->Flags &
VM_READ) ?
'R' :
'-');
4789 if (!pThr->IsThread)
4794 if (pThr->Tgid != pTask->Tgid)
4799 LOG(
"----> Thread %s %d/%d @ 0x%016llx, Parent 0x%016llx, RealParent 0x%016llx, Protected: %d/%llx\n",
4800 pThr->Comm, pThr->Pid, pThr->Tgid, pThr->Gva,
4801 pThr->Parent, pThr->RealParent,
4802 pThr->Protected, pThr->Protection.Mask);
4809 if (pKThread->IsThread && pKThread->KernelMode)
4811 LOG(
"Kernel Thread %s, P(TG)ID %d/%d, CR3 0x%016llx, TS 0x%016llx, Parent 0x%016llx, " 4812 "RealParent 0x%016llx, ActualParent 0x%016llx, Protected: %d/%llx\n",
4813 pKThread->Comm, pKThread->Pid, pKThread->Tgid,
4817 pKThread->RealParent,
4818 pKThread->ActualParent,
4819 pKThread->Protected,
4820 pKThread->Protection.Mask);
4838 LOG(
"# %04d %s, %llx, '%s'\n",
4841 pProt->Protection.Original,
4842 pProt->NamePattern ? pProt->NamePattern :
"(none)");
4862 if (NULL == Callback)
4872 WARNING(
"[WARNING] Callback failed: 0x%08x\n", status);
4902 WORD userModeTasks = 0;
4907 LOG(
"[LIX-GUEST] Found system state '%d'\n", systemState);
4923 if (pTask->KernelMode)
4930 if (pTerminateTask != NULL)
4940 pTerminateTask = pTask;
4945 pTerminateTask = pTask;
4950 if (pTerminateTask == NULL)
4955 LOG(
"[LIX-GUEST] Found shutdown/reboot task '%s'\n", pTerminateTask->
Comm);
4957 if (userModeTasks > 6)
5009 ERROR(
"[ERROR] IntExceptUserGetOriginator failed with status: 0x%08x\n", status);
5019 ERROR(
"[ERROR] IntExceptGetVictimProcess failed with status: 0x%08x\n", status);
5038 ERROR(
"[ERROR] IntDetoursGstSetReturnValue failed: 0x%08x\n", status);
BOOLEAN StolenTokens
TRUE if credentials for this process have been altered.
char * ProcName
The process name that is always valid. It's set depending which info is available in order: Path...
INTSTATUS IntLixTaskGetTrapFrame(const LIX_TASK_OBJECT *Task, LIX_TRAP_FRAME *TrapFrame)
Retrieves the trap frame for a Linux task.
enum _INTRO_ACTION_REASON INTRO_ACTION_REASON
The reason for which an INTRO_ACTION was taken.
struct _LIX_TASK_OBJECT::@135 Dpi
DPI related information.
LIX_OPAQUE_FIELDS OsSpecificFields
OS-dependent and specific information.
static INTSTATUS IntLixTaskFetchMm(QWORD MmStruct, LIX_TASK_OBJECT *Task, LIX_TASK_OBJECT *Parent)
Fetches the CR3 of a Linux task.
INTSTATUS IntLixTaskGetUserStack(LIX_TASK_OBJECT *Task, QWORD *StackPointer, QWORD *StackBase, QWORD *StackLimit)
Finds the user mode stack limits for a Linux process.
QWORD Cr3
The CR3 for this process.
void IntLixCredsVerify(LIX_TASK_OBJECT *Task)
Verifies whether the credentials of a process has been altered or not.
INTSTATUS IntLixAccessRemoteVmHandler(void *Detour)
Detour handler for __access_remote_vm.
Sent for unauthorized process creation alerts. See EVENT_PROCESS_CREATION_VIOLATION.
BOOLEAN Valid
Set to True if the information in the structure is valid, False otherwise.
void IntLixTaskUninit(void)
Uninitializes the Linux process subsystem.
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
static LIST_HEAD gLixTaskPaths
The list with all cached paths.
void IntLixTaskDumpAsTree(void)
Dump the process tree.
struct _EVENT_MEMCOPY_VIOLATION::@290 Victim
INTSTATUS IntLixMmFindVmaRange(QWORD Gva, LIX_TASK_OBJECT *Task, QWORD *VmaStart, QWORD *VmaEnd)
Finds the VMA limits that contain an address.
An internal error occurred (no memory, pages not present, etc.).
INTRO_PROCESS Victim
The process that was compromised.
BOOLEAN IntPolicyCoreForceBetaIfNeeded(QWORD Flag, INTRO_ACTION *Action)
Checks if a forced action should be taken even if the log-only mode is active.
static INTSTATUS IntLixTaskHandleInjection(QWORD Victim, BOOLEAN Pid, QWORD InjectionFlag, BOOLEAN *Block)
Handles the injection into a protected process.
INTSTATUS IntHookObjectDestroy(HOOK_OBJECT_DESCRIPTOR **Object, DWORD Flags)
Destroy an entire hook object. All regions belonging to this object will be removed.
Describe the introcore protection options.
IG_ARCH_REGS Regs
The current state of the guest registers.
BOOLEAN Created
True if the process was created, False if it was terminated.
DWORD Index
The VCPU number.
#define INTRO_OPT_PROT_DPI_STACK_PIVOT
Enable process creation protection for pivoted stack.
void IntLixTaskDump(void)
Dumps the process list.
MITRE_ID MitreID
The Mitre ID that corresponds to this attack.
char * basename_s(char *path, size_t len)
Returns a pointer inside a path string pointing to the beginning of the file base name...
static LIST_HEAD gLixProtectedTasks
The list with all tasks that are currently protected.
#define CLEAN_PHYS_ADDRESS64(x)
static QWORD IntLixUserToKernelPgd(QWORD Pgd)
Translates the value of a user page global directory to it's corresponding kernel value when KPTI is ...
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.
Event structure for process creation/termination.
INTRO_PROCESS Process
The process that attempted the access.
Measures user mode exceptions checks.
#define PAGE_REMAINING(addr)
INTSTATUS IntReadString(QWORD StrGva, DWORD MinimumLength, BOOLEAN AnsiOnly, char **String, DWORD *StringLength)
Reads a string from the guest kernel memory.
#define for_each_path(_var_name)
list_for_each wrapper used to iterate cached paths.
Event structure for process creation violation events.
CAMI_STRING_ENCODING
Describes the encoding of a string received from the CAMI file.
#define _Out_writes_bytes_(expr)
INTSTATUS IntLixTaskSendExceptionEvent(DWORD Signal, LIX_TASK_OBJECT *Task)
Sends an event that contains the information about signal received by the provided task...
INTSTATUS IntLixVdsoDynamicProtect(void)
This function activates the protection for the vDSO image.
static BOOLEAN IntLixTaskMustLog(const LIX_TASK_OBJECT *Task, BOOLEAN Protected)
Controls whether information about a task must be logged or not.
User-mode non executable zone.
Process creation violation.
static void IntLixTaskPathFree(LIX_TASK_PATH **Path)
Release a LIX_TASK_PATH object.
AGENT_EVENT_TYPE Event
The type of the agent.
LIX_TASK_OBJECT * IntLixTaskFindByGva(QWORD TaskStruct)
Finds Linux process with the provided "task_struct" guest virtual address.
QWORD Gva
The guest virtual address of the task_struct.
static void IntLixTaskSendAgentEvent(LIX_TASK_OBJECT *Task, DWORD ExitCode, BOOLEAN Created)
Sends an agent event.
#define IN_RANGE_INCLUSIVE(x, start, end)
BOOLEAN ShutDown
True if the system process protection is in beta (log-only) mode.
DWORD UmThreads
If the user mode threads events should be logged.
#define INT_SUCCESS(Status)
static BOOLEAN IsListEmpty(const LIST_ENTRY *ListHead)
INTSTATUS IntDetSetReturnValue(DETOUR const *Detour, IG_ARCH_REGS *Registers, QWORD ReturnValue)
Sets the return value for a hooked guest function.
LIX_AGENT_TAG IntLixAgentDecProcRef(const char *Name, BOOLEAN *Removed)
Checks if a process is an agent or not, and decrements the ref count of that name.
#define CR3_LONG_MODE_MASK
QWORD Flags
A combination of ALERT_FLAG_* values describing the alert.
INTSTATUS IntExceptGetVictimProcessCreation(void *Process, INTRO_OBJECT_TYPE ObjectType, EXCEPTION_VICTIM_ZONE *Victim)
This function is used to get the information about the victim for process-creation violation...
static LIX_TASK_PATH * IntLixTaskPathGetByFile(QWORD FileGva)
Get a LIX_TASK_PATH object based on the guest virtual address of a "file" structure.
The action was not allowed because there was no reason to allow it.
INTSTATUS IntLixTaskAddProtected(const char *ProcessName, QWORD ProtectionMask, QWORD Context)
Adds a protected process name pattern.
Event structure for agent injection and termination.
void * InitProcessObj
The LIX_TASK_OBJECT of the 'init' process.
The agent process finished execution.
void sanitize_path(char *path, size_t len, size_t *new_len)
Sanitizes an Unix path by removing trailing path delimiters.
void IntLixTaskUpdateProtection(void)
Adjusts protection for all active Linux processes.
static INTSTATUS IntLixTaskDeactivateExploitProtection(LIX_TASK_OBJECT *Task)
Deactivates exploit protection for a Linux task.
QWORD Parent
Depends if this is a thread or a process.
#define for_each_protected_task(_var_name)
list_for_each wrapper used to iterate protected tasks.
#define INT_STATUS_NOT_NEEDED_HINT
INTSTATUS IntLixTaskIsUserStackPivoted(LIX_TASK_OBJECT *Task, QWORD Ptr, BOOLEAN *IsPivoted)
Verifies whether the stack of a Linux process is pivoted or not.
Process creation violation DPI.
DWORD Tgid
The task Thread-Group-ID.
Describes a user-mode originator.
#define INTRO_OPT_PROT_DPI
Aggregates all the deep process inspection flags.
static LIST_HEAD gLixTasksToProtect
The list with all tasks that should be protected.
static INTSTATUS IntLixTaskCreate(LIX_TASK_OBJECT *Parent, LIX_TASK_OBJECT *RealParent, QWORD TaskStruct, BOOLEAN StaticDetected, LIX_TASK_OBJECT **Task)
Creates a Linux process object.
LIX_TASK_PATH * Path
The path of the file executed.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
#define PROC_OPT_PROT_PTRACE
Blocks thread hijacking attempts inside the target process (Linux only).
LIX_TASK_OBJECT * IntLixTaskProtFindByMm(QWORD MmGva)
Finds the protected Linux process having the provided mm guest virtual address.
DWORD ExitStatus
The exit code of the process.
DWORD OSVersion
Os version.
int IntLixGuestGetSystemState(void)
Get the system state of the Linux guest.
QWORD CreationTime
The creation timestamp for this process.
#define INT_STATUS_NOT_FOUND
static LIX_TASK_PATH * IntLixTaskPathGetByPath(QWORD PathGva, QWORD DentryGva)
Get a LIX_TASK_PATH object based on the guest virtual address of a path string.
DWORD IsPreviousAgent
TRUE if this process is an agent remaining from a previous session.
QWORD Base
The user mode stack base.
#define PAGE_COUNT(addr, bytes)
static const char * gLixTerminatingTasks[]
Linux processes signaling that the guest OS is shutting down.
DWORD RefCount
The number of references for this cache entry.
BOOLEAN IntMatchPatternUtf8(const CHAR *Pattern, const CHAR *String, DWORD Flags)
Matches a pattern using glob match.
PCHAR NamePattern
Full application file name.
Describes a path cache entry.
INTRO_PROCESS CurrentProcess
The agent process.
void IntLixProcUpdateProtectedProcess(const void *Name, const CAMI_STRING_ENCODING Encoding, const CAMI_PROT_OPTIONS *Options)
Updates the protection flags for Linux tasks that should be protected based on options received via C...
void IntLixMmDestroyVmas(LIX_TASK_OBJECT *Task)
Remove protection for the VMAs belonging to a process.
Sent for code/data injection alerts. See EVENT_MEMCOPY_VIOLATION.
EVENT_PROCESS_CREATION_VIOLATION ProcessCreation
static INTSTATUS IntLixTaskAdjustProtections(const LIX_PROTECTED_PROCESS *ProtProc, BOOLEAN Remove)
Adjusts the protection flags for processes associated with the LIX_PROTECTED_PROCESS object...
#define LIX_PTI_PGTABLE_SWITCH_BIT
The bit marking whether the kernel memory is mapped in a PGD.
struct _LIX_PROTECTED_PROCESS::@120 Protection
What protection policies should be applied.
void IntLixCredRemove(LIX_CREDS **Creds)
Removes the integrity protection for the credentials set that belong to a process.
void IntAlertFillCpuContext(BOOLEAN CopyInstruction, INTRO_CPUCTX *CpuContext)
Fills the current CPU context for an alert.
Encapsulates a protected Linux process.
DWORD ErrorCode
The error code of the event. Success is 0.
INTRO_PC_VIOLATION_TYPE PcType
Valid if the current violation is DPI Process Creation Violation.
QWORD RealParent
The process which called fork()
INTSTATUS(* PFUNC_LixTaskIterateTasks)(LIX_TASK_OBJECT *Task)
DWORD CommHash
The CRC32 checksum of the Comm field.
#define INTRO_OPT_PROT_KM_VDSO
Enable vDSO image protection (Linux only).
#define INTRO_MATCH_TRUNCATED
If set, matching functions like IntMatchPatternUtf8 will match up until the first wild char encounter...
#define LIX_CREATE_VERSION(K, Patch, Sublevel)
char * CmdLine
The process command line.
#define INT_STATUS_BREAK_ITERATION
Can be used by iteration callbacks to break the iteration early.
void IntAlertFillVersionInfo(INTRO_VIOLATION_HEADER *Header)
Fills version information for an alert.
struct _EVENT_MEMCOPY_VIOLATION::@289 Originator
QWORD IntAlertProcGetFlags(QWORD ProtectionFlag, const void *Process, INTRO_ACTION_REASON Reason, QWORD AdditionalFlags)
Returns the flags for an alert.
QWORD IntLixGetKernelCr3(QWORD Cr3)
Transforms an user CR3 into a kernel CR3 on systems with KPTI enabled and active. ...
BOOLEAN KptiActive
True if KPTI is enabled on this guest, False if it is not.
#define PAGE_FRAME_NUMBER(addr)
QWORD Feedback
Flags that will be forced to feedback only mode.
QWORD ExeFileDentry
The guest virtual address of the executable file's "dentry" structure.
Execution through API call.
Access Token Manipulation.
INTRO_ACTION_REASON Reason
The reason for which Action was taken.
void IntUDRemoveAllEntriesForCr3(const QWORD Cr3)
Remove all pending UD entries for a given virtual address space.
static INTSTATUS _IntLixTaskStartMap(QWORD TaskGva)
Map the task_struct in order to perform further reads from it without any overhead.
static void IntLixTaskSendBlockedEvent(LIX_TASK_OBJECT *OldTask, LIX_TASK_OBJECT *NewTask, INTRO_ACTION Action, INTRO_ACTION_REASON Reason, DWORD PcType)
Sends a blocked process creation event.
QWORD Limit
The user mode stack limit.
static void IntLixTaskRemoveEntry(LIX_TASK_OBJECT *Task)
Removes a Linux process from the process list.
static void IntLixTaskDumpTree(LIX_TASK_OBJECT *Task, DWORD Level)
Dumps the user mode tasks tree.
static INTSTATUS IntLixTaskFetchCmdLine(LIX_TASK_OBJECT *Process, QWORD BinprmGva)
Fetches the command line for a Linux process on the exec() system call.
GENERIC_ALERT gAlert
Global alert buffer.
DWORD Execs
If exec events should be logged.
LIX_TASK_OBJECT * IntLixTaskFindByPid(DWORD Pid)
Finds the Linux process having the provided PID.
enum _INTRO_OBJECT_TYPE INTRO_OBJECT_TYPE
The type of the object protected by an EPT hook.
static LIST_HEAD gLixTasks
The list with all tasks inside the guest OS.
#define LIX_MM_PROT_MASK
The bit used to mark a memory space as protected.
INTRO_VIOLATION_HEADER Header
The alert header.
QWORD Current
The currently used protection flags.
struct _LIX_TASK_LOG LIX_TASK_LOG
This structure contains control bits for linux process logging.
INTSTATUS IntKernVirtMemFetchDword(QWORD GuestVirtualAddress, DWORD *Data)
Reads 4 bytes from the guest kernel memory.
INTRO_VIOLATION_HEADER Header
The alert header.
INTSTATUS IntCamiUpdateProcessProtectionInfo(void *ProtectedProcess)
Update a process' protection flags using the ones from CAMI.
EVENT_MEMCOPY_VIOLATION Injection
QWORD DataStart
The guest virtual address where the data starts.
#define INITIAL_CRC_VALUE
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.
INTSTATUS IntLixGetInitTask(QWORD *InitTask)
Finds the guest virtual address of the "init_task".
#define IS_KERNEL_POINTER_LIX(p)
static INTSTATUS IntLixTaskCreateInitTask(QWORD TaskGva, LIX_TASK_OBJECT **Task)
Creates the init task object.
DWORD ProtForks
If forks performed by protected processes should be logged.
INTSTATUS IntKernVirtMemFetchQword(QWORD GuestVirtualAddress, QWORD *Data)
Reads 8 bytes from the guest kernel memory.
#define IG_CURRENT_VCPU
For APIs that take a VCPU number as a parameter, this can be used to specify that the current VCPU sh...
EVENT_PROCESS_EVENT Process
static INTSTATUS _IntLixTaskRead(DWORD Offset, DWORD Size, void *Buffer)
Perform a read from the previously mapped "task_struct" structure.
INTRO_CPUCTX CpuContext
The context of the CPU that triggered the alert.
static void IntLixTaskDeactivateProtection(LIX_TASK_OBJECT *Task)
Deactivates protection for a Linux process.
#define INTRO_OPT_EVENT_PROCESSES
Enable process creation and termination events (generates introEventProcessEvent events).
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
The parent of a process has a stolen access token when it created the child.
QWORD Original
The original protection flags as received from integrator.
#define INTRO_OPT_PROT_UM_MISC_PROCS
static void IntLixTaskGetPath(QWORD FileGva, QWORD DPathGva, LIX_TASK_OBJECT *Task)
Read and set the path for a Linux process.
static void IntLixTaskSendTaskEvent(LIX_TASK_OBJECT *Task, DWORD ExitCode, BOOLEAN Created, BOOLEAN Crashed, BOOLEAN StaticDetected)
Sends a process event.
QWORD Current
The currently used options.
INTSTATUS IntLixTaskHandlePtrace(void *Detour)
Handles the ptrace() system call.
static LIX_TASK_PATH * IntLixTaskPathGetByDentry(QWORD FileGva, QWORD PathGva, QWORD DentryGva)
Get the LIX_TASK_PATH object associated with a given path.
static void IntLixTaskSendInjectionEvent(LIX_TASK_OBJECT *Source, LIX_TASK_OBJECT *Victim, INTRO_ACTION Action, INTRO_ACTION_REASON Reason)
Sends an injection event.
static INTSTATUS IntLixTaskIterateThreadNode(QWORD TaskStructGva, PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the threads of a Linux process based on the thread node..
INTRO_PROCESS CurrentProcess
The currently active process.
DWORD Exec
TRUE if the process did exec at least once.
static void IntLixValidateExecStack(LIX_TASK_OBJECT *ParentTask, LIX_TASK_OBJECT *CurrentTask)
Validates the user mode stack of a process upon an exec() system call.
Informational event sent when the remediation tool is injected or terminated. See EVENT_AGENT_EVENT...
INTRO_PROCESS Child
The process that is being created or terminated.
BOOLEAN Valid
TRUE if the values inside this structure are valid.
DWORD IsThread
TRUE if it's a thread, not a process.
INTSTATUS IntTranslateVirtualAddress(QWORD Gva, QWORD Cr3, QWORD *PhysicalAddress)
Translates a guest virtual address to a guest physical address.
INTSTATUS IntLixTaskHandleFork(void *Detour)
Handles the fork() system call performed by a linux process.
INTSTATUS(* PFUNC_IterateListCallback)(QWORD Node, QWORD Aux)
#define PROC_OPT_KILL_ON_EXPLOIT
The parent of a process had a pivoted stack when it created the child.
#define LIX_FIELD(Structure, Field)
Macro used to access fields inside the LIX_OPAQUE_FIELDS structure.
#define HpFreeAndNullWithTag(Add, Tag)
INTSTATUS IntGsRead(DWORD CpuNumber, QWORD *GsValue)
Reads the IA32_GS_BASE guest MSR.
#define INT_STATUS_INVALID_DATA_STATE
#define INT_STATUS_INVALID_INTERNAL_STATE
QWORD Context
The context supplied in the protection policy.
Memory access violations that cross a process boundary.
DWORD AgentTag
Unique agent tag. See INTRO_DEP_AG_TAGS.
static LIX_TASK_PATH * IntLixTaskPathGetRef(LIX_TASK_PATH *Path)
Increases the reference counter for a LIX_TASK_PATH object.
static void InsertAfterList(LIST_ENTRY *Pivot, LIST_ENTRY *Item)
DWORD Forks
If forks should be logged.
Informational event sent when a process is created or terminated by the guest. See EVENT_PROCESS_EVEN...
static void IntLixValidateProcessCreationRights(LIX_TASK_OBJECT *ChildTask, LIX_TASK_OBJECT *ParentTask, INTRO_OBJECT_TYPE ObjectType, INTRO_ACTION *Action, INTRO_ACTION_REASON *Reason)
Validates process creation rights (both PC and DPI).
BOOLEAN Protected
True if the process is protected.
String will be encoded in utf-8.
DWORD ProtExecs
If an exec performed by a protected process should be logged.
QWORD Context
Context from integrator.
INTSTATUS IntLixTaskGetAgentsAsCli(char *CommandLine, DWORD Length)
Returns a string with the command lines of all active agents.
INTSTATUS IntLixTaskHandleExec(void *Detour)
Handles the exec() system call of a linux process.
INTSTATUS IntLixTaskAdd(QWORD TaskGva, QWORD StaticDetected)
Creates and adds a Linux process in the internal list.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
DWORD IntLixTaskGetExecCount(void)
Returns the number of processes that have performed an exec.
size_t strlcpy(char *dst, const char *src, size_t dest_size)
CHAR CommPattern[16]
Process name pattern (supports glob patterns). Will be used if there is no path.
LIST_ENTRY ExploitProtProcLink
Linkage in the protected processes list.
INTSTATUS IntLixTaskGetCurrentTaskStruct(DWORD CpuNumber, QWORD *TaskStruct)
Reads the guest virtual address of the task currently running on a CPU.
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.
INTSTATUS IntLixFileGetDentry(QWORD File, QWORD *Dentry)
Reads the value of the dentry field of the 'struct file'.
#define ALERT_FLAG_NOT_RING0
If set, the alert was triggered in ring 1, 2 or 3.
static void InitializeListHead(LIST_ENTRY *ListHead)
static DWORD IntLixTaskGetDpiMitreId(DWORD Flags)
Returns the MITRE ID for the process creation violation flag.
INTSTATUS IntVirtMemSafeWrite(QWORD Cr3, QWORD VirtualAddress, DWORD Size, void *Buffer, DWORD Ring)
Safely modify guest memory.
DWORD KernelMode
TRUE if this process/thread is inside kernel mode.
Describes the modified zone.
#define UNREFERENCED_PARAMETER(P)
#define PROC_OPT_PROT_EXPLOIT
Blocks malicious execution attempts.
char * Name
The path base name.
void * InstructionCache
The currently used instructions cache.
#define INT_STATUS_DATA_BUFFER_TOO_SMALL
static void IntLixTaskMarkAgent(LIX_TASK_OBJECT *Task)
Marks a Linux process as being an Introcore agent.
LIST_ENTRY Link
Entry inside the gLixProtectedTasks list.
#define PROC_OPT_PROT_CORE_HOOKS
Blocks hooks being set on core user-mode DLLs.
size_t NameLength
The size of the base name.
#define PROC_OPT_PROT_PREVENT_CHILD_CREATION
Prevent the process from creating child processes (other than instances of itself).
INTSTATUS IntLixTaskHandleDoExit(void *Detour)
Handles the exit() system call.
static INTSTATUS IntLixTaskChangeProtectionFlags(LIX_TASK_OBJECT *Task, QWORD NewProtection, QWORD NewRootProtection, QWORD Context)
Adjust the protection of a Linux process based on a new set of rules.
static INTSTATUS IntLixTaskActivateExploitProtection(LIX_TASK_OBJECT *Task)
Activates exploit protection for a Linux task.
LIX_CREDS * Creds
The LIX_CREDS reference for the credentials of this process.
INTRO_PC_VIOLATION_TYPE PcType
The type of process creation violation.
enum _INTRO_ACTION INTRO_ACTION
Event actions.
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.
static QWORD IntLixKernelToUserPgd(QWORD Pgd)
Translates the value of a kernel page global directory to it's corresponding user value when KPTI is ...
#define LIX_PROCESSES_MAX_COUNT
The maximum number of processes allowed.
char * Interpreter
If this was a script executed through an interpretor.
QWORD DentryGva
The guest virtual address of the "dentry" structure associated with this path.
LIX_AGENT_TAG IntLixAgentIncProcRef(const char *Name)
Checks if a process is an agent or not, and increments the ref count of that name.
#define INT_STATUS_INVALID_OBJECT_TYPE
INTSTATUS IntLixTaskHandleVmRw(void *Detour)
Handles the process_vm_writev() system call.
LIX_TASK_OBJECT * IntLixTaskFindByMm(QWORD MmGva)
Finds the Linux process having the provided mm guest virtual address.
__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.
This structure contains control bits for linux process logging.
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
size_t PathLength
The size of the path.
char Comm[LIX_COMM_SIZE]
The short name of the executable.
#define LIX_COMM_SIZE
The maximum size of the process comm.
static INTSTATUS IntLixTaskActivateProtection(LIX_TASK_OBJECT *Task, LIX_TASK_OBJECT *Parent)
Activates protection for a Linux process.
GUEST_STATE gGuest
The current guest state.
LIX_TASK_OBJECT * IntLixTaskFindByCr3(QWORD Cr3)
Finds the Linux process having the provided Cr3.
QWORD MmGva
The guest virtual address of the "mm_struct".
void IntLixMmListVmas(QWORD Mm, LIX_TASK_OBJECT *Process)
LIST_ENTRY Link
The list node.
LIST_ENTRY Link
Linkage in the global task list.
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...
DWORD ProtUmThreads
If events related to threads created by protected process should be logged.
static LIX_PROTECTED_PROCESS * IntLixTaskShouldProtect(const LIX_TASK_OBJECT *Task)
Checks whether a Linux task should be protected or not.
INTRO_PROCESS Originator
The process that attempted the violation.
LIX_TASK_LOG gLixTaskLogLevel
The global structure controlling linux process logging.
BOOLEAN IntLixTaskGuestTerminating(void)
Check whether the guest OS is terminating or not.
#define PROC_OPT_BETA
Process is monitored, but in log-only mode so no actions will be blocked.
INTRO_ACTION Action
The action that was taken as the result of this alert.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
#define PROC_OPT_PROT_WRITE_MEM
Blocks foreign write inside the target process.
INTSTATUS IntLixMmPopulateVmas(LIX_TASK_OBJECT *Task)
Populate the Introcore VMAs linked list by iterating the one inside the guest.
LIX_TASK_OBJECT * IntLixTaskGetCurrent(DWORD CpuNumber)
Finds the task that is currently running on the given CPU.
static void IntLixTaskDestroy(LIX_TASK_OBJECT *Task, DWORD ExitCode)
Destroys a Linux process after protection for it is removed.
DWORD Protected
TRUE if the process is protected.
struct _LINUX_GUEST::@123 Layout
#define LIST_HEAD_INIT(Name)
INTSTATUS IntKernVirtMemPatchQword(QWORD GuestVirtualAddress, QWORD Data)
Writes 8 bytes in the guest kernel memory.
QWORD Beta
Flags that were forced to beta mode.
#define INT_STATUS_INVALID_PARAMETER_1
DWORD KmThreads
If the kernel threads events should be logged.
#define INT_STATUS_NOT_SUPPORTED
INTRO_PROCESS CurrentProcess
The current process.
#define PROC_OPT_REMEDIATE
Any event inside the process will trigger the injection of the remediation tool.
VCPU_STATE * gVcpu
The state of the current VCPU.
BOOLEAN Crashed
True if the process crashed.
static INTSTATUS IntLixTaskIterateThreads(QWORD TaskStructGva, PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the threads of a Linux process.
The action was blocked because there was no exception for it.
DWORD Crc32String(const char *String, DWORD InitialCrc)
Computes the CRC for a NULL-terminated utf-8 string.
INTSTATUS IntLixCredAdd(QWORD CredsGva, LIX_CREDS **Creds)
Adds a cred structure in the integrity protected credentials list.
INTSTATUS IntIcFlushVaSpace(PINS_CACHE Cache, QWORD Cr3)
Flush an entire virtual address space.
char * Path
The full path string.
The agent process started execution.
static INTSTATUS IntLixTaskIterateThreadGroup(QWORD TaskStructGva, PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the threads of a Linux process based on the thread group.
void IntLixTaskDumpProtected(void)
Dumps the list with processes that Introcore should protect.
#define PTRACE_SETFPXREGS
#define CRITICAL(fmt,...)
static INTSTATUS IntLixTaskCreateFromBinprm(LIX_TASK_OBJECT *OriginalTask, QWORD BinprmGva, QWORD PathGva, LIX_TASK_OBJECT *UpdatedTask)
Updates the contents of a previously forked process from it's new linux_binprm (used by the loader)...
BOOLEAN BugCheckInProgress
struct _LIX_TASK_OBJECT::@134 UserStack
User stack information.
INTRO_PROCESS Parent
The parent of the process.
QWORD SourceVirtualAddress
The virtual address of the source buffer.
void IntAlertFillLixCurrentProcess(INTRO_PROCESS *EventProcess)
Saves the current Linux process inside an event.
INTSTATUS IntLixTaskIterateTasks(PFUNC_LixTaskIterateTasks Callback)
Call the Callback parameter for each task saved internally.
QWORD DestinationVirtualAddress
The virtual address of the destination buffer.
Exploitation for Client Execution.
BYTE Version
The version field of the version string.
QWORD ActualParent
The parent, based on tgid. Only relevant for threads.
static void IntLixTaskSetProcName(LIX_TASK_OBJECT *Task)
Sets the name for a Linux process.
INTSTATUS IntLixTaskIterateGuestTasks(PFUNC_IterateListCallback Callback, QWORD Aux)
Iterates the guest process list and calls the provided callback for each process and thread found...
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
static DWORD IntLixTaskGetDpiViolationFlags(LIX_TASK_OBJECT *Task)
Returns the DPI flags for a Linux process.
static void _IntLixTaskFinishMap(void)
Unmaps a previously mapped "task_struct".
#define for_each_task(_var_name)
list_for_each wrapper used to iterate Linux tasks.
#define list_for_each(_head, _struct_type, _var)
#define for_each_task_to_protect(_var_name)
list_for_each wrapper used to iterate tasks that should be protected.
DWORD CurrentTaskOffset
The offset of the current task from GS.
INTSTATUS IntLixTaskRemoveProtected(const char *ProcessName)
Removes a pattern of processes to be protected.
void IntAlertFillLixProcess(const LIX_TASK_OBJECT *Task, INTRO_PROCESS *EventProcess)
Saves information about a Linux process inside an event.
#define for_next_task(_task, _var_name)
list_for_next wrapper used to iterate tasks from a given node.
#define ZONE_WRITE
Used for write violation.
#define INT_STATUS_INVALID_PARAMETER_2
INTRO_PROT_OPTIONS CoreOptions
The activation and protection options for this guest.
LIST_HEAD Vmas
The list head for the VMAs from the memory space of this process.
INTSTATUS IntHookObjectCreate(DWORD ObjectType, QWORD Cr3, void **Object)
Create a new hook object.
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.
struct _LIX_TASK_OBJECT::@133 Protection
Protection specific flags.
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
#define INT_STATUS_INVALID_DATA_SIZE
INTSTATUS IntLixFileGetPath(QWORD FileStructGva, char **Path, DWORD *Length)
Gets the path that corresponds to the provided FileStructGva (guest virtual address of the 'struct fi...
DWORD StaticDetected
TRUE if the process was detected using a static scan (during static init).
static void IntLixTaskDumpKernelThreadTree(LIX_TASK_OBJECT *Thread, DWORD Level)
Dumps the kthreads tree.
#define INT_STATUS_INSUFFICIENT_RESOURCES
QWORD Mask
The protection flags enabled for this process.
#define INT_STATUS_INVALID_PARAMETER_3
LIX_AGENT_TAG AgentTag
The agent tag, if this process is an agent.