114 BYTE *pSyscallCode = NULL;
115 QWORD syscallGva = 0;
117 BYTE stiCount, neededStiCount;
122 bFound = bStiFound =
FALSE;
127 if (NULL == pSyscallCode)
132 if (
LIX_FIELD(Info, HasAlternateSyscall))
144 ERROR(
"[ERROR] IntKernVirtMemRead failed for syscall 0x%016llx: 0x%08x\n", syscallGva, status);
152 NDSTATUS ndstatus = NdDecodeEx(&instrux, pSyscallCode + parsed,
PAGE_SIZE - parsed, ND_CODE_64, ND_DATA_64);
153 if (!ND_SUCCESS(ndstatus))
155 ERROR(
"[ERROR] NdDecodeEx failed at 0x%016llx: 0x%08x\n", syscallGva + parsed, ndstatus);
163 if (ND_INS_STI == instrux.Instruction)
165 if (++stiCount == neededStiCount)
171 else if ((instrux.Length >= MinLen) && !ND_HAS_PREDICATE(&instrux))
175 *InstructionVa = syscallGva + parsed;
176 *InstructionLen = instrux.Length;
178 memcpy(InstructionBytes, instrux.InstructionBytes, ND_MAX_INSTRUCTION_LENGTH);
183 parsed += instrux.Length;
218 if (
memcmp_len(pName->Name, Name, pName->Length, nameLength) == 0)
220 ERROR(
"[ERROR] An agent with the name '%s' is already injected!\n", Name);
300 if (Agid == pName->Agid)
329 if (Agid == pName->Agid)
331 return pName->AgentTag;
353 if (Thread->Data.Code != NULL)
386 if (Agent->Data.Address == 0)
398 ERROR(
"[ERROR] IntSlackFree failed with status: 0x%08x.", status);
404 ERROR(
"[ERROR] IntVirtMemMap failed with status: 0x%08x. Cannot fill slack with NOPs...", status);
408 memset(pSlack, 0x90, Agent->Data.Size);
416 Agent->Thread = NULL;
419 if (Agent->Data.Code)
462 ERROR(
"[ERROR] IntVirtMemRead failed with status: 0x%08x.", status);
469 if (Data->Code == NULL)
483 ERROR(
"[ERROR] IntVirtMemRead failed with status: 0x%08x.", status);
487 Data->Address = crtAddress;
519 if (Data->Code == NULL)
524 memcpy(Data->Code, Handler->Code.Content, Handler->Code.Length);
527 Data->Size = Handler->Code.Length;
552 if (Handler->Code.Length != 0)
576 Function->Version.Version ==
BYTE_MAX) &&
578 Function->Version.Patch ==
BYTE_MAX) &&
580 Function->Version.Sublevel ==
WORD_MAX) &&
582 Function->Version.Backport ==
WORD_MAX));
619 DWORD currentFunc = 0;
623 for (
DWORD index = 0; index < Handler->Functions.Count; index++)
627 pFunctions = &Handler->Functions.Content[index];
632 if (pFunctions == NULL)
637 for (
DWORD index = 0; index < pFunctions->
Count; index++)
641 for (
DWORD item = 0; item < pFunctions->
List[index].
Count; item++)
646 TRACE(
"[LIX-AGENT] Found '%s' ksym @ 0x%16llx.", pFunctions->
List[index].
Name[item], kallsymAddr);
652 WARNING(
"[WARNING] IntLixGuestFindKsymByName failed for `%s`\n", pFunctions->
List[index].
Name[item]);
660 if (required > match)
662 ERROR(
"[ERROR] Failed to find required kallsyms for agent.\n");
668 Handler->Args.Content, Handler->Args.Length);
691 if (Agent->Data.Address == 0)
696 ERROR(
"[ERROR] IntSlackAlloc failed with status: 0x%08x.", status);
752 TRACE(
"[LIX-AGENT] Create agent with tag %d ...", Tag);
755 if (pHandler == NULL)
773 ERROR(
"[ERROR] IntLixAgentFillContent failed: 0x%x", status);
780 ERROR(
"[ERROR] IntLixAgentResolveOffset failed: 0x%x", status);
785 pAgent->
TagEx = TagEx;
842 if (pHandler == NULL)
860 ERROR(
"[ERROR] IntLixAgentFillContent failed: 0x%x", status);
867 ERROR(
"[ERROR] IntLixAgentResolveOffset failed: 0x%x", status);
916 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
920 status =
IntLixAgentCreate(Tag, 0, HypercallCallback, CompletionCallback, &pAgent);
923 ERROR(
"[ERROR] IntLixAgentCreateAgent failed with status: 0x%08x.", status);
929 TRACE(
"[AGENT] Linux agent allocated and initialized!\n");
934 ERROR(
"[ERROR] IntLixAgentActivatePendingAgent failed with status: 0x%08x.", status);
988 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
1000 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
1016 ERROR(
"[ERROR] IntLixAgentCreateAgent failed with status: 0x%08x.", status);
1028 ERROR(
"[ERROR] IntLixAgentThreadCreate failed with status: 0x%08x.", status);
1041 ERROR(
"[ERROR] IntLixAgentNameCreate failed with status: 0x%08x.", status);
1049 TRACE(
"[AGENT] Linux agent allocated and initialized!\n");
1054 ERROR(
"[ERROR] IntLixAgentActivatePendingAgent failed with status: 0x%08x.", status);
1097 BYTE instrux[ND_MAX_INSTRUCTION_LENGTH];
1115 memset(&instrux, 0x90,
sizeof(instrux));
1117 TRACE(
"[LIX-AGENT] Found pending agent with tag %d.", pAgent->
Tag);
1131 ERROR(
"[ERROR] IntAgentFindInstruction failed with status: 0x%08x\n", status);
1138 ERROR(
"[LIX-AGENT] IntLixAgentAllocate failed with status: 0x%08x.", status);
1146 ERROR(
"[ERROR] IntKernVirtMemWrite failed with status: 0x%x", status);
1169 TRACE(
"[LIX-AGENT] Agent with tag %d deployed...", pAgent->
Tag);
1205 ERROR(
"[ERROR] Error occurred while running the agent with tag '%d' (%d)...", Agent->Tag, Agent->TagEx);
1210 LOG(
"[LIX-AGENT] '%s' failed with status: %llx", ksymbol, pRegs->
R9);
1245 ERROR(
"[ERROR] IntMemClkUncloakRegion failed with status: 0x%08x\n", status);
1249 Agent->Instruction.CloakHandle = NULL;
1250 Agent->Instruction.Restored =
TRUE;
1252 pRegs->
Rip = Agent->Data.Address + Agent->Data.Header.DataSize;
1254 TRACE(
"[LIX-AGENT] Deployed agent @ 0x%llx and entry point @ %llx", Agent->Data.Address, pRegs->
Rip);
1259 ERROR(
"[ERROR] IntSetGprs failed with status: 0x%08x.\n", status);
1260 ERROR(
"[ERROR] Remove agent with tag '%d' (%d) ...", Agent->Tag, Agent->TagEx);
1268 LOG(
"[LIX-AGENT] Agent with tag '%d' (%d) start execution on VCPU %d at RIP %llx ...",
1294 if (!Agent->Instruction.Restored)
1296 ERROR(
"[LIX-AGENT] Original instruction not restored at exit stage...");
1300 pRegs->
Rip = Agent->Instruction.Address;
1305 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
1309 if (Agent->Thread == NULL)
1320 ERROR(
"[ERROR] IntAgentActivatePendingAgent failed: 0x%08x\n", status);
1348 if (Agent->Data.Token.Hypercall == token)
1350 if (Agent->Callback.Hypercall == NULL)
1355 status = Agent->Callback.Hypercall(Agent);
1358 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1364 if (Agent->Data.Token.Completion == token)
1366 if (Agent->Callback.Completion == NULL)
1371 status = Agent->Callback.Completion(Agent);
1374 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1380 if (Agent->Data.Token.Error == token)
1385 ERROR(
"[LIX-AGENT] IntLixAgentError failed with status: 0x%08x.", status);
1391 if (Rip == (Agent->Data.Address + Agent->Data.Header.ExitOffset))
1396 ERROR(
"[LIX-AGENT] IntLixAgentExit failed with status: 0x%08x.", status);
1402 ERROR(
"[ERROR] Breakpoint generated an exit from unrecognized rip ...");
1429 ERROR(
"[ERROR] Error occurred while running the agent-thread with tag '%d' (%d)...",
1430 Agent->Thread->Tag, Agent->TagEx);
1435 LOG(
"[LIX-AGENT] '%s' failed with status: %llx", ksymbol, pRegs->
R9);
1465 LOG(
"[LIX-AGENT] Agent-thread with tag '%d' (%d) completed ...", Agent->Thread->Tag, Agent->TagEx);
1476 ERROR(
"[ERROR] IntAgentActivatePendingAgent failed");
1514 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1530 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1541 ERROR(
"[LIX-AGENT] IntLixAgentThreadError failed with status %0x08x.", status);
1552 ERROR(
"[ERROR] IntLixAgentThreadExit failed with status: 0x%08x.", status);
1558 ERROR(
"[ERROR] Breakpoint generated an exit from unrecognized rip inside agent-thread '%d'...",
1591 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1617 ERROR(
"[ERROR] IntLixAgentStart failed with status: 0x%08x.", status);
1629 ERROR(
"[ERROR] IntLixAgentHandleBreakpoint failed with status: 0x%08x.", status);
1635 if (pAgent->
Thread != NULL &&
1641 ERROR(
"[ERROR] IntLixAgentThreadHandleBreakpoint failed with status: 0x%08x.", status);
1661 ERROR(
"[ERROR] VMCALL executed from kernel mode. Rip 0x%016llx.",
gVcpu->
Regs.
Rip);
1704 LOG(
"[LIX-AGENT] User-mode stub reports error for agent with tag %d: 0x%08x\n",
1710 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%x\n", status);
1718 LOG(
"[WARNING] VMCALL coming from outside a process with CR3 %llx\n", pRegs->
Cr3);
1724 TRACE(
"[AGENT-LIX] VMCALL with op = %lld from `%s` (PID = %d) which is not an agent (previous = %d), " 1734 ERROR(
"[ERROR] IntAgentHandleRemediationVmcall failed: 0x%08x\n", status);
1743 ERROR(
"[ERROR] IntAgentHandleLogGatherVmcall failed: 0x%08x\n", status);
1773 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1782 ERROR(
"[LIX-AGENT] VMCALL with no active agent from RIP 0x%016llx.", Rip);
1884 length = strlen(Name);
1888 if (0 == strncmp(Name, pName->Name, length))
1892 return pName->AgentTag;
1926 length = strlen(Name);
1930 if (
memcmp_len(Name, pName->Name, length, pName->Length) == 0)
1934 if (pName->RefCount > 0)
1940 WARNING(
"[WARNING] Agent %s already done by our logic!\n", pName->Name);
1943 if (pName->RefCount == 0)
1979 memzero(&gLixAgentState,
sizeof(gLixAgentState));
1986 LOG(
"[LIX-AGENT] Linux agent state initialized.\n");
2015 memzero(&gLixAgentState,
sizeof(gLixAgentState));
2056 ERROR(
"[ERROR] IntVirtMemWrite failed with status: 0x%08x.", status);
2064 ERROR(
"[ERROR] IntSetGprs failed with status: 0x%08x.", status);
2074 Agent->Thread = NULL;
2095 DWORD errorCode = 0;
2097 if (pRegs->
Rax == 0)
2103 LOG(
"[DEPLOYER] Agent with tag %d has just been injected, error: 0x%08x.", Agent->TagEx, errorCode);
2130 memzero(pEvent,
sizeof(*pEvent));
2132 pEvent->
Event = Event;
2139 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%x\n", status);
WORD DataSize
The size (bytes) of the data.
INTSTATUS IntLixAgentUninit(void)
Uninit the agents state.
TIMER_FRIENDLY void IntDumpArchRegs(IG_ARCH_REGS const *Registers)
This function dumps the register values in a user friendly format.
AG_WAITSTATE IntLixAgentGetState(DWORD *Tag)
Gets the global agents state.
static DWORD IntLixAgentGetId(void)
Generate a new ID.
void IntLixAgentEnableInjection(void)
Enables agent injections.
#define CONTAINING_RECORD(List, Type, Member)
LIX_AGENT_TAG Tag
The internal tag.
INTSTATUS IntVirtMemUnmap(void **HostPtr)
Unmaps a memory range previously mapped with IntVirtMemMap.
static INTSTATUS IntLixAgentAllocate(LIX_AGENT *Agent)
Allocate a memory zone for the content of the agent.
CHAR Name[IG_MAX_AGENT_NAME_LENGTH]
The name of the agent.
INTSTATUS IntLixAgentHandleVmcall(QWORD Rip)
Handle a VMCALL that was executed inside the guest.
WORD CodeSize
The size (byes) of the code.
Describes a handlers that contains the data required by the agent.
LIX_AGENT_DATA Data
The data used by the agent.
LIX_TASK_OBJECT * IntLixTaskFindByCr3(QWORD Cr3)
Finds the Linux process having the provided Cr3.
QWORD Completion
The token used by completion callback.
INTSTATUS IntKernVirtMemWrite(QWORD KernelGva, DWORD Length, void *Buffer)
Writes data to a guest kernel virtual memory range.
No active/pending agents.
IG_ARCH_REGS Regs
The current state of the guest registers.
struct _LIX_AGENT_TOKEN LIX_AGENT_TOKEN
The tokens used by an agent.
static LIX_AGENT_STATE gLixAgentState
DWORD Index
The VCPU number.
LIX_AGENT_HANDLER * IntLixAgentGetHandlerByTag(LIX_AGENT_TAG AgentTag)
Iterates through all agent handlers and search the entry that has the provided tag.
void IntLixAgentInit(void)
Initialize the agents state.
QWORD SystemCr3
The Cr3 used to map the kernel.
#define INT_STATUS_SUCCESS
LIX_AGENT_HEADER Header
The header of the agent's data.
DWORD Count
The number of function names.
enum _LIX_AGENT_TAG LIX_AGENT_TAG
Tag used to identify an agent with a handler.
#define INT_STATUS_DISASM_ERROR
Indicates a decoder error.
We have at least pending agent waiting to be injected inside the guest.
#define _Out_writes_bytes_(expr)
struct _LIX_AGENT_THREAD::@93 Callback
DWORD Size
The size (bytes) of the injected agent.
LIX_AGENT_HYPERCALL HypercallType
The hypercall type used.
#define IntEnterDebugger()
Describes an agent-thread running inside the guest.
void IntLixAgentDisablePendingAgents(void)
Disables all pending agents.
struct _LIST_ENTRY * Flink
INTSTATUS(* PFUNC_AgentCallbackHypercall)(void *Context)
Hypercall callback prototype.
#define AGENT_HCALL_INTERNAL
Reserved for internal use.
AGENT_EVENT_TYPE Event
The type of the agent.
INTSTATUS IntLixAgentHandleInt3(QWORD Rip)
Called when a INT3 instruction from the current running agent is executed.
INTSTATUS IntKsymFindByAddress(QWORD Gva, DWORD Length, char *SymName, QWORD *SymStart, QWORD *SymEnd)
Finds the symbol which is located at the given address.
LIST_ENTRY Link
List entry element.
#define INT_SUCCESS(Status)
static BOOLEAN IsListEmpty(const LIST_ENTRY *ListHead)
INTSTATUS IntResumeVcpus(void)
Resumes the VCPUs previously paused with IntPauseVcpus.
AGENT_EVENT_TYPE
The state of an agent.
DWORD TagEx
The tag provided by the integrator.
INTSTATUS IntVirtMemWrite(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer)
Writes data to a guest virtual memory range.
Event structure for agent injection and termination.
QWORD Hypercall
The token used by hypercall callback.
Describe an agent running inside the guest.
void IntLixAgentNameRemoveByAgid(DWORD Agid)
Iterates through all agent names and removes the entry that contains the provided ID...
INTSTATUS(* PFUNC_AgentCallbackCompletion)(void *Context)
Completion callback prototype.
#define INT_STATUS_NOT_NEEDED_HINT
size_t Length
Name length.
Header with information about running code inside the guest.
#define HpAllocWithTag(Len, Tag)
int INTSTATUS
The status data type.
static int memcmp_len(const void *buf1, const void *buf2, size_t len_buf1, size_t len_buf2)
LIX_AGENT_TAG AgentTag
Agent tag.
#define INT_STATUS_NOT_FOUND
LIX_AGENT_THREAD * Thread
A pointer to a agent-thread, if any.
DWORD IsPreviousAgent
TRUE if this process is an agent remaining from a previous session.
struct _LIX_AGENT::@96 Instruction
#define IMAGE_BASE_NAME_LEN
The maximum length of a process name.
static INTSTATUS IntLixAgentCreate(LIX_AGENT_TAG Tag, DWORD TagEx, PFUNC_AgentCallbackHypercall HypercallCallback, PFUNC_AgentCallbackCompletion CompletionCallback, LIX_AGENT **Agent)
Create an agent entry.
struct _LINUX_GUEST::@125::@129 Agent
INTSTATUS IntPauseVcpus(void)
Pauses all the guest VCPUs.
INTRO_GUEST_TYPE OSType
The type of the guest.
LIST_HEAD PendingAgents
List of agents waiting to be injected.
DWORD RefCount
Number of times this name has been used by agents.
DWORD ErrorCode
The error code of the event. Success is 0.
Will write the contents of the patched data inside the guest.
INTSTATUS IntSlackAlloc(QWORD ModuleBase, BOOLEAN Pageable, DWORD Size, QWORD *Buffer, QWORD SecHint)
Allocate slack inside the guest.
static INTSTATUS IntLixAgentFillDataFromHandler(LIX_AGENT_DATA *Data, LIX_AGENT_HANDLER *Handler)
Fetch the content of the agent with the provided LIX_AGENT_TAG from the corresponding LIX_AGENT_HANDL...
DWORD Count
The number of the functions list.
INTSTATUS IntAgentHandleLogGatherVmcall(void *Reserved, PIG_ARCH_REGS Registers)
Handle a VMCALL issued by a log gather agent.
char Name[IMAGE_BASE_NAME_LEN]
Image base name.
static INTSTATUS IntLixAgentCreateThreadHypercall(LIX_AGENT *Agent)
Called by the thread-agent to deploy the content of the kthread previously created.
enum _LIX_AGENT_HYPERCALL HypercallType
The hypercall type.
static INTSTATUS IntLixAgentThreadCreate(LIX_AGENT_TAG Tag, PFUNC_AgentCallbackHypercall HypercallCallback, PFUNC_AgentCallbackCompletion CompletionCallback, BYTE *ContentAddress, DWORD ContentSize, LIX_AGENT_THREAD **Thread)
Create an agent-thread entry.
BOOLEAN IntLixAgentMatchVersion(LIX_AGENT_FUNCTIONS *Function)
Checks if the provided LIX_AGENT_FUNCTIONS match the current guest version.
The agent has been successfully injected.
DWORD CompletingAgentsCount
Number of agents that are yet to complete execution.
char * Name[256]
The function name.
GENERIC_ALERT gAlert
Global alert buffer.
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 AGENT_HCALL_GATHER_TOOL
Log gathering tool.
LIST_ENTRY Link
List entry element.
#define INT_STATUS_ALREADY_INITIALIZED
#define INT_STATUS_NOT_INITIALIZED
BYTE * Address
A pointer to the content provided by the integrator.
BYTE * Code
A buffer that contains the in-guest agent code/data.
void * CloakHandle
Cloak handle used to hide the detoured instruction.
struct _LIX_AGENT::@95 Callback
INTSTATUS IntNotifyIntroEvent(INTRO_EVENT_TYPE EventClass, void *Param, size_t EventSize)
Notifies the integrator about an introspection alert.
LIX_AGENT_TAG IntLixAgentIncProcRef(const char *Name)
Checks if a process is an agent or not, and increments the ref count of that name.
BOOLEAN SafeToInjectProcess
Will be true the moment it's safe to inject agents (the OS has booted).
static BOOLEAN RemoveEntryList(LIST_ENTRY *Entry)
LIX_AGENT_TAG Tag
The internal tag.
Informational event sent when the remediation tool is injected or terminated. See EVENT_AGENT_EVENT...
#define IN_RANGE_LEN(x, start, len)
static INTSTATUS IntLixAgentHandleBreakpoint(LIX_AGENT *Agent, QWORD Rip)
Called when a INT3 instruction from the current running agent is hit.
static void IntLixAgentNameRemove(LIX_AGENT_NAME *Name)
Frees and removes from our list the provided LIX_AGENT_NAME.
struct _LIX_AGENT_NAME LIX_AGENT_NAME
Describes the name of an injected process agent.
#define LIX_FIELD(Structure, Field)
Macro used to access fields inside the LIX_OPAQUE_FIELDS structure.
LIST_HEAD AgentNames
List of agent names.
#define HpFreeAndNullWithTag(Add, Tag)
INTSTATUS IntMemClkCloakRegion(QWORD VirtualAddress, QWORD Cr3, DWORD Size, DWORD Options, PBYTE OriginalData, PBYTE PatchedData, PFUNC_IntMemCloakWriteHandle WriteHandler, void **CloakHandle)
Hides a memory zone from the guest.
DWORD AgentTag
Unique agent tag. See INTRO_DEP_AG_TAGS.
QWORD KernelVa
The guest virtual address at which the kernel image.
INTSTATUS IntIcFlushAddress(PINS_CACHE Cache, QWORD Gva, QWORD Cr3)
Flush entries cached from a given address.
#define AGENT_HCALL_REM_TOOL
Used by the remediation tool.
static void InsertTailList(LIST_ENTRY *ListHead, LIST_ENTRY *Entry)
#define INT_STATUS_NO_DETOUR_EMU
Signals that no emulation is needed for this event.
static INTSTATUS IntLixAgentHandleKernelVmcall(void)
Called when a VMCALL instruction from the current running agent is executed.
size_t strlcpy(char *dst, const char *src, size_t dest_size)
static INTSTATUS IntLixAgentFindInstruction(BYTE MinLen, QWORD *InstructionVa, BYTE *InstructionLen, BYTE *InstructionBytes)
Searches for a suitable instruction to replace with a INT3 instruction.
BOOLEAN Initialized
True if the agents state has been initialized.
static void InitializeListHead(LIST_ENTRY *ListHead)
#define LIX_SYMBOL_NAME_LEN
The max length of the ksym as defined by Linux kernel.
Describes the name of an injected process agent.
enum _AGENT_TYPE AGENT_TYPE
INTSTATUS IntSlackFree(QWORD Buffer)
Free slack space.
static INTSTATUS IntLixAgentThreadError(LIX_AGENT *Agent)
Called when an error occurred while the running the current thread-agent.
void * InstructionCache
The currently used instructions cache.
QWORD Address
The address of the kthread.
void IntLixAgentSendEvent(AGENT_EVENT_TYPE Event, DWORD AgentTag, DWORD ErrorCode)
Send an event to the integrator that contains the AGENT_EVENT_TYPE, tag of the agent and the last err...
The tokens used by an agent.
static uint64_t __rdtsc(void)
INTSTATUS IntSetGprs(DWORD CpuNumber, PIG_ARCH_REGS Regs)
Sets the values of the guest GPRs.
static INTSTATUS IntLixAgentHandleUserVmcall(void)
Handles a VMCALL issued by a process that has been injected inside the guest.
__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.
QWORD Address
Address of the detoured instruction.
DWORD IntLixAgentNameGetTagByAgid(DWORD Agid)
Iterates through all agent names and returns the tag of the agent that has the provided agent ID...
MM Mm
Guest memory information, such as paging mode, system Cr3 value, etc.
static INTSTATUS IntLixAgentFillDataFromMemory(LIX_AGENT_DATA *Data, LIX_AGENT_TAG Tag)
Fetch the content of the agent with the provided LIX_AGENT_TAG from memory.
char Comm[LIX_COMM_SIZE]
The short name of the executable.
GUEST_STATE gGuest
The current guest state.
PFUNC_AgentCallbackCompletion Completion
Completion callback.
LIX_AGENT_HYPERCALL HypercallType
The hypercall type.
INTSTATUS IntVirtMemRead(QWORD Gva, DWORD Length, QWORD Cr3, void *Buffer, DWORD *RetLength)
Reads data from a guest virtual memory range.
The functions required by the agent.
static INTSTATUS IntEnableBreakpointNotifications(void)
static INTSTATUS IntDisableBreakpointNotifications(void)
Describes the data of an agent.
LIX_AGENT_FUNCTIONS_LIST List[20]
An array that contains LIX_AGENT_FUNCTIONS_LIST entries.
LIX_AGENT_HANDLER * IntLixAgentThreadGetHandlerByTag(LIX_AGENT_TAG AgentTag, LIX_AGENT_TAG ThreadTag)
Iterates through all thread-agent handlers and search the entry that has the provided tag...
struct _LIX_AGENT_STATE LIX_AGENT_STATE
The global agents state.
BYTE Bytes[16]
Detoured instruction bytes.
INTSTATUS IntKernVirtMemRead(QWORD KernelGva, DWORD Length, void *Buffer, DWORD *RetLength)
Reads data from a guest kernel virtual memory range.
The agent or the process stub reports an error.
static INTSTATUS IntLixAgentFillData(LIX_AGENT_DATA *Data, LIX_AGENT_HANDLER *Handler)
Fetch the content of the agent.
static INTSTATUS IntLixAgentNameCreate(const char *Name, DWORD Tag, DWORD Agid, LIX_AGENT_NAME **AgentName)
Create an agent name and insert the newly create agent-name to linked list.
#define LIST_HEAD_INIT(Name)
static INTSTATUS IntLixAgentThreadFree(LIX_AGENT_THREAD *Thread)
Remove the provided agent-thread.
DWORD Required
The number of required function addresses for the 'Name' array.
static INTSTATUS IntLixAgentResolveOffset(LIX_AGENT_DATA *Data, LIX_AGENT_HANDLER *Handler)
Search the functions and complete the args/tokens required by the agent.
QWORD Error
The token used by error callback.
QWORD SyscallAddress
The guest virtual address of the syscall.
static QWORD IntLixAgentGetToken(void)
Randomly select a token to be used by the agent code when issuing hyper calls.
DWORD CurrentId
Used to generate unique agent IDs.
#define INT_STATUS_NOT_SUPPORTED
INTSTATUS IntLixAgentThreadInject(LIX_AGENT_TAG Tag, DWORD TagEx, AGENT_TYPE AgentType, PFUNC_AgentCallbackHypercall HypercallCallback, PFUNC_AgentCallbackCompletion CompletionCallback, const char *Name, BYTE *ContentAddress, DWORD ContentSize)
Schedule an thread-agent injection inside the guest.
INTSTATUS IntMemClkUncloakRegion(void *CloakHandle, DWORD Options)
Removes a cloak region, making the original memory contents available again to the guest...
VCPU_STATE * gVcpu
The state of the current VCPU.
static INTSTATUS IntLixAgentExit(LIX_AGENT *Agent)
Called when the agent is terminating.
static INTSTATUS IntLixAgentCreateThreadCompletion(LIX_AGENT *Agent)
Called by the thread-agent when the kthread started.
Process agent. A process will be injected & started inside the guest.
QWORD Address
The guest virtual address of the injected agent.
enum _AG_WAITSTATE AG_WAITSTATE
LIX_AGENT_DATA Data
The data used by the agent.
INTSTATUS IntGetCurrentRing(DWORD CpuNumber, DWORD *Ring)
Read the current protection level.
LIX_AGENT_TOKEN Token
The tokens of the agent.
PFUNC_AgentCallbackHypercall Hypercall
Hypercall callback.
#define UNREFERENCED_LOCAL_VARIABLE(V)
BYTE Version
The version field of the version string.
BYTE Length
Detoured instruction length.
QWORD IntKsymFindByName(const char *Name, QWORD *SymEnd)
Searches the given Name in kallsyms and returns the Start & End offset.
static INTSTATUS IntLixAgentError(LIX_AGENT *Agent)
Called when an error occurred while the running the current agent.
#define list_for_each(_head, _struct_type, _var)
INTSTATUS IntLixAgentInject(LIX_AGENT_TAG Tag, PFUNC_AgentCallbackHypercall HypercallCallback, PFUNC_AgentCallbackCompletion CompletionCallback)
Schedule an agent injection inside the guest.
We have an active agent, currently injected inside the guest.
static INTSTATUS IntLixAgentThreadHandleBreakpoint(LIX_AGENT *Agent, QWORD Rip)
Called when a INT3 instruction from the current running thread-agent is hit.
static INTSTATUS IntLixAgentStart(LIX_AGENT *Agent)
Called when the INT3 instruction from SYSCALL is hit.
PFUNC_AgentCallbackCompletion Completion
Completion callback.
DWORD Tag
The LIX_AGENT_TAG.
INTSTATUS IntLixAgentActivatePendingAgent(void)
Activates a pending agent that waits to be injected.
struct _LINUX_GUEST::@125 MmAlloc
static void IntLixAgentFree(LIX_AGENT *Agent)
Remove the provided agent.
LIX_AGENT * ActiveAgent
The active agent at any given moment. This is the one.
static BOOLEAN IntLixAgentNameIsRunning(const char *Name)
Iterates through all agent names to check if an agent with the provided name is running.
QWORD PropperSyscallGva
The guest virtual address of the 'real' syscall.
LINUX_GUEST * gLixGuest
Global variable holding the state of a Linux guest.
PFUNC_AgentCallbackHypercall Hypercall
Hypercall callback.
static INTSTATUS IntLixAgentThreadExit(LIX_AGENT *Agent)
Called when the thread-agent is terminating.
struct _LIX_AGENT_THREAD::@94 Content
#define INT_STATUS_INSUFFICIENT_RESOURCES
DWORD Size
The size of the content provided by the integrator.
WORD ExitOffset
The offset of the INT3 instruction that represent the exit point.
BOOLEAN Restored
True if the detours instruction has been restored.
LIX_AGENT_TAG AgentTag
The agent tag, if this process is an agent.