115 BYTE *pSyscallCode = NULL;
116 QWORD syscallGva = 0;
118 BYTE stiCount, neededStiCount;
123 bFound = bStiFound =
FALSE;
128 if (NULL == pSyscallCode)
133 if (
LIX_FIELD(Info, HasAlternateSyscall))
145 ERROR(
"[ERROR] IntKernVirtMemRead failed for syscall 0x%016llx: 0x%08x\n", syscallGva, status);
153 NDSTATUS ndstatus = NdDecodeEx(&instrux, pSyscallCode + parsed,
PAGE_SIZE - parsed, ND_CODE_64, ND_DATA_64);
154 if (!ND_SUCCESS(ndstatus))
156 ERROR(
"[ERROR] NdDecodeEx failed at 0x%016llx: 0x%08x\n", syscallGva + parsed, ndstatus);
164 if (ND_INS_STI == instrux.Instruction)
166 if (++stiCount == neededStiCount)
172 else if ((instrux.Length >= MinLen) && !ND_HAS_PREDICATE(&instrux))
176 *InstructionVa = syscallGva + parsed;
177 *InstructionLen = instrux.Length;
179 memcpy(InstructionBytes, instrux.InstructionBytes, ND_MAX_INSTRUCTION_LENGTH);
184 parsed += instrux.Length;
219 if (
memcmp_len(pName->Name, Name, pName->Length, nameLength) == 0)
221 ERROR(
"[ERROR] An agent with the name '%s' is already injected!\n", Name);
301 if (Agid == pName->Agid)
330 if (Agid == pName->Agid)
332 return pName->AgentTag;
354 if (Thread->Data.Code != NULL)
359 if (Thread->Content.Address)
392 if (Agent->Data.Address == 0)
404 ERROR(
"[ERROR] IntSlackFree failed with status: 0x%08x.", status);
410 ERROR(
"[ERROR] IntVirtMemMap failed with status: 0x%08x. Cannot fill slack with NOPs...", status);
414 memset(pSlack,
LIX_FIELD(Info, HasSlackInt3) ? 0xCC : 0x90, Agent->Data.Size);
422 Agent->Thread = NULL;
425 if (Agent->Data.Code)
468 ERROR(
"[ERROR] IntVirtMemRead failed with status: 0x%08x.", status);
475 if (Data->Code == NULL)
489 ERROR(
"[ERROR] IntVirtMemRead failed with status: 0x%08x.", status);
493 Data->Address = crtAddress;
525 if (Data->Code == NULL)
530 memcpy(Data->Code, Handler->Code.Content, Handler->Code.Length);
533 Data->Size = Handler->Code.Length;
558 if (Handler->Code.Length != 0)
582 Function->Version.Version ==
BYTE_MAX) &&
584 Function->Version.Patch ==
BYTE_MAX) &&
586 Function->Version.Sublevel ==
WORD_MAX) &&
588 Function->Version.Backport ==
WORD_MAX));
625 DWORD currentFunc = 0;
629 for (
DWORD index = 0; index < Handler->Functions.Count; index++)
633 pFunctions = &Handler->Functions.Content[index];
638 if (pFunctions == NULL)
643 for (
DWORD index = 0; index < pFunctions->
Count; index++)
647 for (
DWORD item = 0; item < pFunctions->
List[index].
Count; item++)
652 TRACE(
"[LIX-AGENT] Found '%s' ksym @ 0x%16llx.", pFunctions->
List[index].
Name[item], kallsymAddr);
658 WARNING(
"[WARNING] IntLixGuestFindKsymByName failed for `%s`\n", pFunctions->
List[index].
Name[item]);
666 if (required > match)
668 ERROR(
"[ERROR] Failed to find required kallsyms for agent.\n");
674 Handler->Args.Content, Handler->Args.Length);
697 if (Agent->Data.Address == 0)
702 ERROR(
"[ERROR] IntSlackAlloc failed with status: 0x%08x.", status);
758 TRACE(
"[LIX-AGENT] Create agent with tag %d ...", Tag);
761 if (pHandler == NULL)
779 ERROR(
"[ERROR] IntLixAgentFillContent failed: 0x%x", status);
786 ERROR(
"[ERROR] IntLixAgentResolveOffset failed: 0x%x", status);
791 pAgent->
TagEx = TagEx;
848 if (pHandler == NULL)
866 ERROR(
"[ERROR] IntLixAgentFillContent failed: 0x%x", status);
873 ERROR(
"[ERROR] IntLixAgentResolveOffset failed: 0x%x", status);
922 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
926 status =
IntLixAgentCreate(Tag, 0, HypercallCallback, CompletionCallback, &pAgent);
929 ERROR(
"[ERROR] IntLixAgentCreateAgent failed with status: 0x%08x.", status);
935 TRACE(
"[AGENT] Linux agent allocated and initialized!\n");
940 ERROR(
"[ERROR] IntLixAgentActivatePendingAgent failed with status: 0x%08x.", status);
994 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
1006 WARNING(
"[WARNING] Tried to create an agent but the agent state not initialized.");
1022 ERROR(
"[ERROR] IntLixAgentCreateAgent failed with status: 0x%08x.", status);
1034 ERROR(
"[ERROR] IntLixAgentThreadCreate failed with status: 0x%08x.", status);
1047 ERROR(
"[ERROR] IntLixAgentNameCreate failed with status: 0x%08x.", status);
1055 TRACE(
"[AGENT] Linux agent allocated and initialized!\n");
1060 ERROR(
"[ERROR] IntLixAgentActivatePendingAgent failed with status: 0x%08x.", status);
1103 BYTE instrux[ND_MAX_INSTRUCTION_LENGTH];
1121 memset(&instrux, 0x90,
sizeof(instrux));
1123 TRACE(
"[LIX-AGENT] Found pending agent with tag %d.", pAgent->
Tag);
1137 ERROR(
"[ERROR] IntAgentFindInstruction failed with status: 0x%08x\n", status);
1144 ERROR(
"[LIX-AGENT] IntLixAgentAllocate failed with status: 0x%08x.", status);
1152 ERROR(
"[ERROR] IntKernVirtMemWrite failed with status: 0x%x", status);
1175 TRACE(
"[LIX-AGENT] Agent with tag %d deployed...", pAgent->
Tag);
1211 ERROR(
"[ERROR] Error occurred while running the agent with tag '%d' (%d)...", Agent->Tag, Agent->TagEx);
1216 LOG(
"[LIX-AGENT] '%s' failed with status: %llx", ksymbol, pRegs->
R9);
1251 ERROR(
"[ERROR] IntMemClkUncloakRegion failed with status: 0x%08x\n", status);
1255 Agent->Instruction.CloakHandle = NULL;
1256 Agent->Instruction.Restored =
TRUE;
1258 pRegs->
Rip = Agent->Data.Address + Agent->Data.Header.DataSize;
1260 TRACE(
"[LIX-AGENT] Deployed agent @ 0x%llx and entry point @ %llx", Agent->Data.Address, pRegs->
Rip);
1265 ERROR(
"[ERROR] IntSetGprs failed with status: 0x%08x.\n", status);
1266 ERROR(
"[ERROR] Remove agent with tag '%d' (%d) ...", Agent->Tag, Agent->TagEx);
1274 LOG(
"[LIX-AGENT] Agent with tag '%d' (%d) start execution on VCPU %d at RIP %llx ...",
1300 if (!Agent->Instruction.Restored)
1302 ERROR(
"[LIX-AGENT] Original instruction not restored at exit stage...");
1306 pRegs->
Rip = Agent->Instruction.Address;
1311 ERROR(
"[ERROR] IntSetGprs failed: 0x%08x\n", status);
1315 if (Agent->Thread == NULL)
1326 ERROR(
"[ERROR] IntAgentActivatePendingAgent failed: 0x%08x\n", status);
1354 if (Agent->Data.Token.Hypercall == token)
1356 if (Agent->Callback.Hypercall == NULL)
1361 status = Agent->Callback.Hypercall(Agent);
1364 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1370 if (Agent->Data.Token.Completion == token)
1372 if (Agent->Callback.Completion == NULL)
1377 status = Agent->Callback.Completion(Agent);
1380 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1386 if (Agent->Data.Token.Error == token)
1391 ERROR(
"[LIX-AGENT] IntLixAgentError failed with status: 0x%08x.", status);
1397 if (Rip == (Agent->Data.Address + Agent->Data.Header.ExitOffset))
1402 ERROR(
"[LIX-AGENT] IntLixAgentExit failed with status: 0x%08x.", status);
1408 ERROR(
"[ERROR] Breakpoint generated an exit from unrecognized rip ...");
1435 ERROR(
"[ERROR] Error occurred while running the agent-thread with tag '%d' (%d)...",
1436 Agent->Thread->Tag, Agent->TagEx);
1441 LOG(
"[LIX-AGENT] '%s' failed with status: %llx", ksymbol, pRegs->
R9);
1471 LOG(
"[LIX-AGENT] Agent-thread with tag '%d' (%d) completed ...", Agent->Thread->Tag, Agent->TagEx);
1482 ERROR(
"[ERROR] IntAgentActivatePendingAgent failed");
1520 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1536 ERROR(
"[LIX-AGENT] Agent callback failed with status %0x08x.", status);
1547 ERROR(
"[LIX-AGENT] IntLixAgentThreadError failed with status %0x08x.", status);
1558 ERROR(
"[ERROR] IntLixAgentThreadExit failed with status: 0x%08x.", status);
1564 ERROR(
"[ERROR] Breakpoint generated an exit from unrecognized rip inside agent-thread '%d'...",
1597 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1623 ERROR(
"[ERROR] IntLixAgentStart failed with status: 0x%08x.", status);
1635 ERROR(
"[ERROR] IntLixAgentHandleBreakpoint failed with status: 0x%08x.", status);
1641 if (pAgent->
Thread != NULL &&
1647 ERROR(
"[ERROR] IntLixAgentThreadHandleBreakpoint failed with status: 0x%08x.", status);
1667 ERROR(
"[ERROR] VMCALL executed from kernel mode. Rip 0x%016llx.",
gVcpu->
Regs.
Rip);
1710 LOG(
"[LIX-AGENT] User-mode stub reports error for agent with tag %d: 0x%08x\n",
1716 WARNING(
"[WARNING] IntNotifyIntroEvent failed: 0x%x\n", status);
1724 LOG(
"[WARNING] VMCALL coming from outside a process with CR3 %llx\n", pRegs->
Cr3);
1730 TRACE(
"[AGENT-LIX] VMCALL with op = %lld from `%s` (PID = %d) which is not an agent (previous = %d), " 1740 ERROR(
"[ERROR] IntAgentHandleRemediationVmcall failed: 0x%08x\n", status);
1749 ERROR(
"[ERROR] IntAgentHandleLogGatherVmcall failed: 0x%08x\n", status);
1779 ERROR(
"[ERROR] IntGetCurrentRing failed: 0x%08x\n", status);
1788 ERROR(
"[LIX-AGENT] VMCALL with no active agent from RIP 0x%016llx.", Rip);
1890 length = strlen(Name);
1894 if (0 == strncmp(Name, pName->Name, length))
1898 return pName->AgentTag;
1932 length = strlen(Name);
1936 if (
memcmp_len(Name, pName->Name, length, pName->Length) == 0)
1940 if (pName->RefCount > 0)
1946 WARNING(
"[WARNING] Agent %s already done by our logic!\n", pName->Name);
1949 if (pName->RefCount == 0)
1985 memzero(&gLixAgentState,
sizeof(gLixAgentState));
1992 LOG(
"[LIX-AGENT] Linux agent state initialized.\n");
2021 memzero(&gLixAgentState,
sizeof(gLixAgentState));
2062 ERROR(
"[ERROR] IntVirtMemWrite failed with status: 0x%08x.", status);
2070 ERROR(
"[ERROR] IntSetGprs failed with status: 0x%08x.", status);
2080 Agent->Thread = NULL;
2101 DWORD errorCode = 0;
2103 if (pRegs->
Rax == 0)
2109 LOG(
"[DEPLOYER] Agent with tag %d has just been injected, error: 0x%08x.", Agent->TagEx, errorCode);
2136 memzero(pEvent,
sizeof(*pEvent));
2138 pEvent->
Event = Event;
2145 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.
struct _LINUX_GUEST::@128 MmAlloc
LIX_AGENT_DATA Data
The data used by the agent.
struct _LINUX_GUEST::@128::@132 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)
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.
#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.
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.
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 IntReleaseBuffer(void *Buffer, DWORD Size)
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.
struct _LIX_AGENT_THREAD::@96 Callback
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.
struct _LIX_AGENT_THREAD::@97 Content
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.
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.
struct _LIX_AGENT::@99 Instruction
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::@98 Callback
#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.