Bitdefender Hypervisor Memory Introspection
|
This file deals with Windows agents injection. More...
#include "winagent.h"
#include "alerts.h"
#include "guests.h"
#include "hnd_loggather.h"
#include "hnd_remediation.h"
#include "icache.h"
#include "kernvm.h"
#include "loader.h"
#include "memcloak.h"
#include "ptfilter.h"
#include "slack.h"
#include "vecore.h"
#include "winbootdrv_Win32.h"
#include "winbootdrv_x64.h"
#include "winpe.h"
#include "winprocesshp.h"
#include "winstubs.h"
Go to the source code of this file.
Data Structures | |
struct | _AGENT_NAME |
struct | _AGENT_STATE |
Macros | |
#define | REM_DRV(arch64) ((arch64) ? (gBootDriverx64) : (gBootDriverWin32)) |
#define | REM_SIZE(arch64) ((arch64) ? (sizeof(gBootDriverx64)) : sizeof((gBootDriverWin32))) |
#define | AGENT_FLAG_STARTED 0x00000001 |
#define | AGENT_FLAG_ALLOCATED 0x00000002 |
#define | AGENT_FLAG_ACTIVE 0x00000004 |
#define | AGENT_FLAG_COMPLETED 0x00000008 |
#define | AGENT_FLAG_ALL_DONE 0x0000000F |
Typedefs | |
typedef struct _AGENT_NAME | AGENT_NAME |
typedef struct _AGENT_NAME * | PAGENT_NAME |
typedef struct _AGENT_STATE | AGENT_STATE |
typedef struct _AGENT_STATE * | PAGENT_STATE |
Functions | |
BOOLEAN | IntWinAgentIsRipInsideCurrentAgent (QWORD Rip) |
Return true if the given RIP points inside the currently active boot driver. More... | |
INTSTATUS | IntWinAgentSelectBootstrapAddress (DWORD Size, QWORD *Address) |
Finds an in-guest adders that can be used to host the bootstrap code. More... | |
INTSTATUS | IntWinAgentReleaseBootstrapAddress (QWORD Address) |
Releases the slack space allocated for the bootstrap code. More... | |
static INTSTATUS | IntWinAgentFree (PWIN_AGENT Agent, QWORD DataInfo) |
Frees an agent. More... | |
static INTSTATUS | IntWinAgentRemove (PWIN_AGENT Agent) |
Removes the given agent. More... | |
INTSTATUS | IntWinAgentInjectTrampoline (void) |
Inject the agent trampoline inside the guest. More... | |
static INTSTATUS | IntWinAgentDeployWinDriver (PWIN_AGENT Agent) |
Inject the Windows boot driver. More... | |
static INTSTATUS | IntWinAgentFindPropperSyscall (QWORD *PropperSyscall) |
Find the main SYSCALL handler. More... | |
static INTSTATUS | IntWinAgentFindSyscallLinkage (DWORD SyscallNumber, QWORD *LinkageAddress) |
Find the address of the kernel linkage of a syscall. More... | |
static INTSTATUS | IntWinAgentFindInstruction (BYTE MinLen, QWORD *InstructionVa, BYTE *InstructionLen, BYTE *InstructionBytes) |
Searches for a suitable instruction to replace with a CALL to the trampoline code. More... | |
INTSTATUS | IntWinAgentActivatePendingAgent (void) |
Activates a pending agent that waits to be injected. More... | |
static INTSTATUS | IntWinAgentRestoreState64 (PWIN_AGENT Agent, PIG_ARCH_REGS Registers) |
Restore the general purpose registers state. More... | |
static INTSTATUS | IntWinAgentRestoreState32 (PWIN_AGENT Agent, PIG_ARCH_REGS Registers) |
Restore the general purpose registers state. More... | |
static INTSTATUS | IntWinAgentHandleBreakpointAgent (PWIN_AGENT Agent, PIG_ARCH_REGS Registers) |
Handle an INT3 that was initiated by a breakpoint agent. More... | |
static INTSTATUS | IntWinAgentHandleLoader1Hypercall (WIN_AGENT *Agent, IG_ARCH_REGS *Registers) |
Handle a hyper call initiated by the trampoline code. More... | |
static INTSTATUS | IntWinAgentReleaseBootstrap (WIN_AGENT *Agent, IG_ARCH_REGS *Registers) |
Releases the bootstrap allocated inside the guest. More... | |
static INTSTATUS | IntWinAgentRemoveAgentAndResetState (WIN_AGENT *Agent) |
Removes the indicated agent. More... | |
static INTSTATUS | IntWinAgentReleaseBootstrapAndRemoveAgent (WIN_AGENT *Agent, IG_ARCH_REGS *Registers) |
Releases the bootstrap address and removes the agent. More... | |
static INTSTATUS | IntWinAgentHandleLoader2Hypercall (PWIN_AGENT Agent, PIG_ARCH_REGS Registers) |
Handles VMCALLs issued by the bootstrap code. More... | |
static INTSTATUS | IntWinAgentHandleDriverVmcall (PWIN_AGENT Agent, PIG_ARCH_REGS Registers) |
This function handles VMCALLs issued by the boot driver. More... | |
static INTSTATUS | IntWinAgentHandleAppVmcall (void *Reserved, PIG_ARCH_REGS Registers) |
Handles a VMCALL issued by an application that has been injected inside the guest. More... | |
INTSTATUS | IntWinAgentHandleInt3 (QWORD Rip, DWORD CpuNumber) |
Handle a breakpoint that was initiated inside the guest. More... | |
INTSTATUS | IntWinAgentHandleVmcall (QWORD Rip) |
Handle a VMCALL that was executed inside the guest. More... | |
static void | IntWinAgentSelectTokens (QWORD *Token1, QWORD *Token2, QWORD *Token3) |
Randomly select 3 tokens to be used by the bootstrap code when issuing hyper calls. More... | |
INTSTATUS | IntWinAgentInject (PFUNC_AgentInjection InjectionCallback, PFUNC_AgentCompletion CompletionCallback, PFUNC_AgentDeliver DeliverCallback, void *Context, PBYTE AgentContent, DWORD AgentSize, BOOLEAN AgentInternal, DWORD AgentTag, AGENT_TYPE AgentType, const CHAR *Name, DWORD Options, const CHAR *Args, DWORD Pid, PWIN_AGENT *Agent) |
Schedule an agent injection inside the guest. More... | |
INTSTATUS | IntWinAgentInjectBreakpoint (PFUNC_AgentInjection InjectionCallback, void *Context, PWIN_AGENT *Agent) |
Injects a breakpoint agent inside the guest. More... | |
INTSTATUS | IntWinAgentEnableInjection (void) |
enables agent injections. More... | |
void | IntWinAgentCheckIfProcessAgentAndIncrement (CHAR *ImageName, BOOLEAN *IsAgent, DWORD *Tag) |
Checks if a process is an agent or not, and increments the ref count of that name. More... | |
void | IntWinAgentCheckIfProcessAgentAndDecrement (CHAR *ImageName, BOOLEAN *IsAgent, DWORD *Tag, BOOLEAN *Removed) |
Checks if a process is an agent or not, and decrements the ref count of that name. More... | |
void | IntWinAgentRemoveEntryByAgid (DWORD Counter, DWORD *Tag) |
Removes an agent name from the list of names, using the ID. More... | |
BOOLEAN | IntWinAgentIsPtrInTrampoline (QWORD Ptr, THS_PTR_TYPE Type) |
Check if the provided address points inside the agent trampoline. More... | |
AG_WAITSTATE | IntWinAgentGetState (DWORD *Tag) |
Gets the global agents state. More... | |
void | IntWinAgentDisablePendingAgents (void) |
Disables all pending agents. More... | |
void | IntWinAgentInit (void) |
Initialize the agents state. More... | |
INTSTATUS | IntWinAgentUnInit (void) |
Uninit the agents state. More... | |
Variables | |
BYTE | gTrampolineZero [4096] = {0} |
Just a page filled with zeros. More... | |
static AGENT_STATE | gAgentState = {0} |
This file deals with Windows agents injection.
Introcore supports injecting agents inside the guest VM. An agent is a file, process or driver which is deployed inside the guest, and which is removed when it is not needed anymore. Typical agents usage include:
0. Detoured instruction. This is an instruction inside the SYSCALL handler, which gets executed by the operating system, and which we replace with a "CALL" to the trampoline code (see the next section). The instruction must be at least 5 bytes in size (since 5 is the length of the relative "CALL" we use). Once a SYSCALL is generated and the detoured instruction is hit, the trampoline code gets activated. In case we want to inject a breakpoint agent, we replace this instruction with just a breakpoint, so instead of going through the trampoline, the breakpoint would be handled directly, without the intervention of the trampoline.
NOTE: There can be only one active agent at any time (by active agent we mean an instance of the boot driver). NOTE: When injecting a process, the boot driver will return as soon as the process was started; this means that it does not wait for the process to finish, allowing Introcore to inject other agents in the meantime, so there can be an arbitrary number of active injected processes at any given time. NOTE: When injecting processes, the IntWinAgentInject function accepts a PID argument which represents the process the agent should be started from. If this argument is 0, the injected process agent will be started in the context of the winlogon.exe process, with SYSTEM privileges!!! NOTE: IntKernVirtMemWrite can be used only for buffers that were allocated/validated by Introcore. For buffers sent from within the guest, use IntVirtMemSafeWrite instead, which validates both the guest page tables and the EPT and ring rights in order to see if the buffer is safe to be written.
Definition in file winagent.c.
#define AGENT_FLAG_ACTIVE 0x00000004 |
Definition at line 142 of file winagent.c.
Referenced by IntWinAgentReleaseBootstrap().
#define AGENT_FLAG_ALL_DONE 0x0000000F |
Definition at line 144 of file winagent.c.
Referenced by IntWinAgentHandleBreakpointAgent(), IntWinAgentHandleLoader1Hypercall(), and IntWinAgentHandleLoader2Hypercall().
#define AGENT_FLAG_ALLOCATED 0x00000002 |
Definition at line 141 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall().
#define AGENT_FLAG_COMPLETED 0x00000008 |
Definition at line 143 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall().
#define AGENT_FLAG_STARTED 0x00000001 |
Definition at line 140 of file winagent.c.
Referenced by IntWinAgentHandleBreakpointAgent(), and IntWinAgentHandleLoader1Hypercall().
#define REM_DRV | ( | arch64 | ) | ((arch64) ? (gBootDriverx64) : (gBootDriverWin32)) |
Definition at line 137 of file winagent.c.
Referenced by IntWinAgentDeployWinDriver(), and IntWinAgentInject().
#define REM_SIZE | ( | arch64 | ) | ((arch64) ? (sizeof(gBootDriverx64)) : sizeof((gBootDriverWin32))) |
Definition at line 138 of file winagent.c.
Referenced by IntWinAgentDeployWinDriver(), and IntWinAgentInject().
typedef struct _AGENT_NAME AGENT_NAME |
Describes the name of an injected process agent. Whenever a named agent is injected, we allocate such an entry. Whenever a process is created, we check if its name matches the name of an injected agent; if it does, it will be flagged as being an agent. Therefore, it is advisable to use complicated names for the agents, in order to avoid having regular processes marked as agents.
typedef struct _AGENT_STATE AGENT_STATE |
Global agents state.
typedef struct _AGENT_NAME * PAGENT_NAME |
typedef struct _AGENT_STATE * PAGENT_STATE |
INTSTATUS IntWinAgentActivatePendingAgent | ( | void | ) |
Activates a pending agent that waits to be injected.
This function will inject a pending agent. The steps required are:
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 920 of file winagent.c.
Referenced by IntAgentActivatePendingAgent(), IntWinAgentEnableInjection(), IntWinAgentHandleInt3(), IntWinAgentHandleVmcall(), IntWinAgentInject(), and IntWinAgentInjectBreakpoint().
void IntWinAgentCheckIfProcessAgentAndDecrement | ( | CHAR * | ImageName, |
BOOLEAN * | IsAgent, | ||
DWORD * | Tag, | ||
BOOLEAN * | Removed | ||
) |
Checks if a process is an agent or not, and decrements the ref count of that name.
Each time a process terminates, we check if it was an agent, and we decrement the reference count if its name. Once the reference count of an agent name reaches 0, it will be removed.
[in] | ImageName | The image name of the process which is checked. |
[out] | IsAgent | True if the process is agent, false otherwise. |
[out] | Tag | The agent tag, if the process is found to be an agent. |
[out] | Removed | True if the agent was removed. |
Definition at line 3084 of file winagent.c.
Referenced by IntWinProcDeleteProcessObject().
void IntWinAgentCheckIfProcessAgentAndIncrement | ( | CHAR * | ImageName, |
BOOLEAN * | IsAgent, | ||
DWORD * | Tag | ||
) |
Checks if a process is an agent or not, and increments the ref count of that name.
Each time a process is created, we check if its name matches the name of a previously injected agent. If it does, we flag that process as an agent, and we increment the reference count of the name.
[in] | ImageName | The image name of the process which is checked. |
[out] | IsAgent | True if the process is agent, false otherwise. |
[out] | Tag | The agent tag, if the process is found to be an agent. |
Definition at line 3028 of file winagent.c.
Referenced by IntWinProcCreateProcessObject().
|
static |
Inject the Windows boot driver.
This function injects the Windows boot driver inside the guest. The boot driver will be written at an address that was previously allocated by the boot code. Once the Windows boot driver is written inside the guest memory, the boot code will start a thread pointing inside the boot driver.
[in] | Agent | The agent handle. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_OPERATION_NOT_IMPLEMENTED | If the guest OS is not Windows. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
INT_STATUS_NOT_FOUND | If the entry point of the boot driver is not found. |
Definition at line 451 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall().
void IntWinAgentDisablePendingAgents | ( | void | ) |
Disables all pending agents.
This function should be called during the uninit phase, as it will disable all the pending agents. These agents will never be injected inside the guest. The only exception is given by the VE or PT unloaders, which must be injected on uninit in order to remove the VE or PT drivers from the guest memory.
Definition at line 3291 of file winagent.c.
Referenced by IntAgentDisablePendingAgents().
INTSTATUS IntWinAgentEnableInjection | ( | void | ) |
enables agent injections.
INT_STATUS_SUCCESS | On success. |
Definition at line 3010 of file winagent.c.
Referenced by IntAgentEnableInjection().
|
static |
Searches for a suitable instruction to replace with a CALL to the trampoline code.
Will try to find, starting with the SYSCALL/SYSENTER address, the first "STI" instruction and then the first instruction that's at least 5 bytes in length; this instruction will host our CALL towards the agent trampoline. On x64, we will seek the 3rd STI instruction. The first 2 get executed on a very rare path. If we inject a breakpoint agent, we will replace the instruction with an INT3 instead of a CALL.
[in] | MinLen | Unused. |
[in] | InstructionVa | The guest virtual address where a suitable instruction was found. |
[in] | InstructionLen | The length of the identified instruction. |
[in] | InstructionBytes | Actual instruction bytes. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 772 of file winagent.c.
Referenced by IntWinAgentActivatePendingAgent().
Find the main SYSCALL handler.
This function finds the main SYSCALL handler. Note that on KPTI systems, the SYSCALL MSR points to a shadow SYSCALL handler, which only does the CR3 switch, and then jumps to the main SYSCALL handler, which is interesting to us.
[in] | PropperSyscall | Will contain, upon successful return, the address of the main SYSCALL handler. |
INT_STATUS_SUCCESS | On success. |
Definition at line 576 of file winagent.c.
Referenced by IntWinAgentFindInstruction().
|
static |
Find the address of the kernel linkage of a syscall.
Will use kernel buffer if available.
[in] | SyscallNumber | The number of the syscall to be searched for. |
[out] | LinkageAddress | The address of the syscall kernel linkage. |
Definition at line 675 of file winagent.c.
Referenced by IntWinAgentHandleDriverVmcall().
|
static |
Frees an agent.
This function frees an agent and all the resources allocated to it, for example, its contents. NOTE: The contents of the agent may have been memory-mapped by the integrator; if this is the case, we cannot correctly free it ourselves; instead, we call a dedicated glue API which notifies the integrator that it is safe to free the memory allocated for the agent.
[in] | Agent | The agent to be freed. |
[in] | DataInfo | Unused. |
INT_STATUS_SUCCESS | On success. |
Definition at line 238 of file winagent.c.
Referenced by IntWinAgentDisablePendingAgents(), and IntWinAgentRemove().
AG_WAITSTATE IntWinAgentGetState | ( | DWORD * | Tag | ) |
Gets the global agents state.
[out] | Tag | Optional agent tag, if an agent is active or pending. |
agActive | If there's an active agent. |
agWaiting | If there's a pending agent. |
agNone | If there are no active or pending agents. |
Definition at line 3245 of file winagent.c.
Referenced by IntAgentGetState().
|
static |
Handles a VMCALL issued by an application that has been injected inside the guest.
Each injected application should have its own private VMCALL structure, depending on what information it wants to report. Currently, Introcore can digest VMCALLs from two types of applications:
[in] | Reserved | Reserved for future use. |
[in] | Registers | General purpose registers state. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 2162 of file winagent.c.
Referenced by IntWinAgentHandleVmcall().
|
static |
Handle an INT3 that was initiated by a breakpoint agent.
This function simply calls the injection callback. This function is used by the breakpoint agents, which are simple agents that only trigger a breakpoint on the SYSCALL flow, where it is safe to inject kernel page-faults or call kernel APIs. Once the injection callback is called, the agent will be freed. NOTE: The ring must already be validated.
[in] | Agent | The agent to be injected. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_SUCCESS | On success, if the breakpoint has already been handled. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_NO_DETOUR_EMU | If the breakpoint was handled by this instance. |
Definition at line 1332 of file winagent.c.
Referenced by IntWinAgentHandleInt3().
|
static |
This function handles VMCALLs issued by the boot driver.
The boot driver may issue several VMCALLs which will be handled by Introcore. The defined VMCALLs are:
[in] | Agent | The currently active agent. |
[in] | Registers | General purpose registers state. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 1816 of file winagent.c.
Referenced by IntWinAgentHandleVmcall().
Handle a breakpoint that was initiated inside the guest.
This function will search for an appropriate handler for the breakpoint. There are several causes for such breakpoints:
[in] | Rip | Unused. |
[in] | CpuNumber | The VCPU number on which the event took place. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_FOUND | If a handler is not found. |
Definition at line 2273 of file winagent.c.
Referenced by IntAgentHandleInt3().
|
static |
Handle a hyper call initiated by the trampoline code.
First HYPERCALL inside the trampoline hit. We have to store in RAX the address of the bootstrap, we have to restore the old, patched instruction, and we have to patch the return address for the call in order to return to the actual "interrupted" instruction.
NOTE: The ring must already be validated.
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_NOT_FOUND | If the current RIP does not point inside the trampoline code. |
Definition at line 1422 of file winagent.c.
Referenced by IntWinAgentHandleInt3().
|
static |
Handles VMCALLs issued by the bootstrap code.
This function handles hyper calls issued by the bootstrap code. There are 3 hyper calls defined:
[in] | Agent | The agent. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_NO_DETOUR_EMU | If the VMCALL was handled by this function. |
INT_STATUS_NOT_FOUND | If the VMCALL was not issued by the bootstrap code. |
Definition at line 1675 of file winagent.c.
Referenced by IntWinAgentHandleInt3().
Handle a VMCALL that was executed inside the guest.
This function handles VMCALLs that took place inside the guest. Since the small agent components (trampoline, bootstrap) use INT3, the VMCALL issued by the boot driver and the user-mode applications that get injected by Introcore.
[in] | Rip | The RIP where the VMCALL was initiated. |
INT_STATUS_SUCCESS | On success. |
Definition at line 2397 of file winagent.c.
Referenced by IntAgentHandleVmcall().
void IntWinAgentInit | ( | void | ) |
Initialize the agents state.
Definition at line 3333 of file winagent.c.
Referenced by IntWinGuestNew().
INTSTATUS IntWinAgentInject | ( | PFUNC_AgentInjection | InjectionCallback, |
PFUNC_AgentCompletion | CompletionCallback, | ||
PFUNC_AgentDeliver | DeliverCallback, | ||
void * | Context, | ||
PBYTE | AgentContent, | ||
DWORD | AgentSize, | ||
BOOLEAN | AgentInternal, | ||
DWORD | AgentTag, | ||
AGENT_TYPE | AgentType, | ||
const CHAR * | Name, | ||
DWORD | Options, | ||
const CHAR * | Args, | ||
DWORD | Pid, | ||
PWIN_AGENT * | Agent | ||
) |
Schedule an agent injection inside the guest.
This function schedules the injection of an agent inside the guest space. If this function succeeds means that the injection has been successfully scheduled; it does not mean that the agent has been successfully injected. This function can be used to inject files or processes inside the guest. This function is also used to inject the VE and PT agents inside the guest. Due to the 3 callbacks architecture, it is very flexible and it allows the caller to extend this mechanism with his own defined callbacks.
[in] | InjectionCallback | This callback is called after the boot driver has been successfully injected inside the guest. |
[in] | CompletionCallback | This callback is called after the boot driver has finished execution, and the agent is being removed from memory. |
[in] | DeliverCallback | This callback is called by VE and PT handlers inside the boot driver. This callback basically allows us to inject a next stage agent, and to initialize it, without having to rely on the guest for that. |
[in] | Context | Optional agent context. |
[in] | AgentContent | Pointer to a memory area containing the actual agent. |
[in] | AgentSize | The size of the agent, in bytes. |
[in] | AgentInternal | True if this is an internal agent (statically allocated inside Introcore). |
[in] | AgentTag | Agent tag. Check out AGENT_TAG* for more info. |
[in] | AgentType | Agent type. Check out AGENT_TYPE* for more info. |
[in] | Name | Agent name. |
[in] | Options | Agent options. |
[in] | Args | Agent arguments. Passed as a command line for process agents. |
[in] | Pid | PID of the process that will be the parent of the agent process. if this is 0, winlogon will be chosen as a parent. |
[in] | Agent | Will contain, in successful return, the handle to the newly scheduled agent. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
INT_STATUS_OPERATION_NOT_IMPLEMENTED | If the current guest is not Windows. |
INT_STATUS_ALREADY_INITIALIZED | If an agent with the same name has already been injected. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 2608 of file winagent.c.
Referenced by IntPtiInjectPtFilter(), IntPtiRemovePtFilter(), IntVeDeployAgent(), IntVeRemoveAgent(), IntWinDepInjectFile(), and IntWinDepInjectProcess().
INTSTATUS IntWinAgentInjectBreakpoint | ( | PFUNC_AgentInjection | InjectionCallback, |
void * | Context, | ||
PWIN_AGENT * | Agent | ||
) |
Injects a breakpoint agent inside the guest.
This function injects a breakpoint agent inside the guest. These breakpoint agents are used simply to generate a breakpoint VM exit on the SYSCALL flow, since that flow is the safest to inject kernel faults or to call kernel APIs.
[in] | InjectionCallback | Callback to be called when the breakpoint is hit. |
[in] | Context | Optional context to be passed to the callback. |
[out] | Agent | Optional agent handle. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_OPERATION_NOT_IMPLEMENTED | If the guest is not Windows. |
INT_STATUS_INSUFFICIENT_RESOURCES | If a memory alloc fails. |
Definition at line 2921 of file winagent.c.
Referenced by IntSwapMemInjectMiniSwapper().
INTSTATUS IntWinAgentInjectTrampoline | ( | void | ) |
Inject the agent trampoline inside the guest.
The agent trampoline is a small chunk of code that gets injected inside a region of NT slack space. This trampoline is used to intermediate the code transfers to the bootstrap code, which is dynamically allocated and must be freed once the agent is done.
INT_STATUS_SUCCESS | On success. |
Definition at line 364 of file winagent.c.
Referenced by IntWinGuestFinishInit().
BOOLEAN IntWinAgentIsPtrInTrampoline | ( | QWORD | Ptr, |
THS_PTR_TYPE | Type | ||
) |
Check if the provided address points inside the agent trampoline.
[in] | Ptr | The pointer to be checked. |
[in] | Type | The pointer type: live RIP or stack value. |
Definition at line 3219 of file winagent.c.
Referenced by IntAgentIsPtrInTrampoline().
Return true if the given RIP points inside the currently active boot driver.
[in] | Rip | The RIP to be checked. |
Definition at line 197 of file winagent.c.
Referenced by IntWinDrvHandleRead().
|
static |
Releases the bootstrap allocated inside the guest.
[in] | Agent | The agent handle. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_NO_DETOUR_EMU | As the call happens on a VMCALL, and we move the RIP ourselves, we do not wish to have this emulated. |
Definition at line 1565 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall(), and IntWinAgentReleaseBootstrapAndRemoveAgent().
Releases the slack space allocated for the bootstrap code.
[in] | Address | The previously allocated bootstrap address. |
INT_STATUS_SUCCESS | On success. |
Definition at line 2548 of file winagent.c.
Referenced by IntWinAgentIsRipInsideCurrentAgent(), and IntWinAgentRemove().
|
static |
Releases the bootstrap address and removes the agent.
[in] | Agent | The agent to be removed. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1641 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall().
|
static |
Removes the given agent.
This function removes an agent. It will restore the hooked instruction and the boot code, and then it will free it.
[in] | Agent | The agent to be removed. |
INT_STATUS_SUCCESS | On success. |
Definition at line 272 of file winagent.c.
Referenced by IntWinAgentActivatePendingAgent(), IntWinAgentHandleBreakpointAgent(), IntWinAgentHandleLoader1Hypercall(), IntWinAgentRemoveAgentAndResetState(), and IntWinAgentUnInit().
Removes the indicated agent.
[in] | Agent | The agent to be removed. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1612 of file winagent.c.
Referenced by IntWinAgentHandleLoader2Hypercall(), and IntWinAgentReleaseBootstrapAndRemoveAgent().
Removes an agent name from the list of names, using the ID.
[in] | Counter | The counter/ID to be removed. |
[out] | Tag | Optional tag of the removed name. |
Definition at line 3171 of file winagent.c.
Referenced by IntWinAgentHandleAppVmcall(), and IntWinAgentHandleDriverVmcall().
|
static |
Restore the general purpose registers state.
This function restores the general purpose registers state after the bootstrap code has finished execution. The transfer from the first section of the bootstrap to the trampoline must be done this way because in rare cases, the thread that we created in the second section of the bootstrap may finish execution BEFORE the first section of the bootstrap gets to return back to the trampoline, and it may lead to a use-after-free situation, where we free the bootstrap inside guest memory before it returned to the trampoline. By doing the transfer ourselves, and using a small semaphore inside the thread, we are ensured that the thread cannot finish execution before the bootstrap returned to the trampoline.
[in] | Agent | The agent. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1263 of file winagent.c.
Referenced by IntWinAgentReleaseBootstrap().
|
static |
Restore the general purpose registers state.
This function restores the general purpose registers state after the bootstrap code has finished execution. The transfer from the first section of the bootstrap to the trampoline must be done this way because in rare cases, the thread that we created in the second section of the bootstrap may finish execution BEFORE the first section of the bootstrap gets to return back to the trampoline, and it may lead to a use-after-free situation, where we free the bootstrap inside guest memory before it returned to the trampoline. By doing the transfer ourselves, and using a small semaphore inside the thread, we are ensured that the thread cannot finish execution before the bootstrap returned to the trampoline.
[in] | Agent | The agent. |
[in] | Registers | The general purpose registers state. |
INT_STATUS_SUCCESS | On success. |
Definition at line 1186 of file winagent.c.
Referenced by IntWinAgentReleaseBootstrap().
Finds an in-guest adders that can be used to host the bootstrap code.
This function will try to allocate slack space inside NT. If no such space is found, it will attempt to find slack space inside another loaded module. This is safe, since the small trampoline code jumps to the bootstrap code via an indirect call (CALL rax), so the bootstrap code doesn't have to be withing [-2G, +2G] of the trampoline.
[in] | Size | The size required for the bootstrap code. |
[out] | Address | Guest virtual address where the bootstrap has been allocated. |
INT_STATUS_SUCCESS | On success. |
INT_STATUS_INVALID_PARAMETER | If an invalid parameter is supplied. |
Definition at line 2481 of file winagent.c.
Referenced by IntWinAgentActivatePendingAgent(), and IntWinAgentIsRipInsideCurrentAgent().
Randomly select 3 tokens to be used by the bootstrap code when issuing hyper calls.
Since we don't want to allow random hyper calls from guest space, we randomly generate 3 tokens which will be passed to Introcore by the bootstrap code. Each token must match when calling Introcore.
[out] | Token1 | The first token. |
[out] | Token2 | The second token. |
[out] | Token3 | The third token. |
Definition at line 2566 of file winagent.c.
Referenced by IntWinAgentInject().
INTSTATUS IntWinAgentUnInit | ( | void | ) |
Uninit the agents state.
INT_STATUS_SUCCESS | On success. |
INT_STATUS_NOT_INITIALIZED_HINT | If the agents state has not been initialized yet. |
Definition at line 3352 of file winagent.c.
Referenced by IntWinGuestUninit().
|
static |
Definition at line 192 of file winagent.c.
BYTE gTrampolineZero[4096] = {0} |
Just a page filled with zeros.
Definition at line 164 of file winagent.c.