Bitdefender Hypervisor Memory Introspection
|
Go to the source code of this file.
Data Structures | |
struct | _WIN_AGENT |
Macros | |
#define | MAX_BOOTSTRAP_SIZE 512u |
Maximum size of the bootstrap code. More... | |
#define | AG_OPT_INJECT_ON_RIP_POWSTATE_CHANGE 0x00000001 |
Typedefs | |
typedef INTSTATUS(* | PFUNC_AgentInjection) (QWORD GuestVirtualAddress, DWORD AgentTag, void *Context) |
Injection callback. More... | |
typedef INTSTATUS(* | PFUNC_AgentCompletion) (QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context) |
Completion callback. More... | |
typedef QWORD(* | PFUNC_AgentDeliver) (QWORD GuestVirtualAddress, DWORD MaxSize, void *Context) |
Called for VE and PT initialization. More... | |
typedef enum _AGENT_HCALL | AGENT_HCALL |
typedef struct _WIN_AGENT | WIN_AGENT |
typedef struct _WIN_AGENT * | PWIN_AGENT |
Enumerations | |
enum | _AGENT_HCALL { AGENT_HCALL_VMCALL, AGENT_HCALL_INT3 } |
Functions | |
BOOLEAN | IntWinAgentIsRipInsideCurrentAgent (QWORD Rip) |
Return true if the given RIP points inside the currently active boot driver. More... | |
INTSTATUS | IntWinAgentHandleVmcall (QWORD Rip) |
Handle a VMCALL that was executed inside the guest. More... | |
INTSTATUS | IntWinAgentHandleInt3 (QWORD Rip, DWORD CpuNumber) |
Handle a breakpoint that was initiated inside the guest. 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 | IntWinAgentInjectTrampoline (void) |
Inject the agent trampoline 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... | |
void | IntWinAgentDisablePendingAgents (void) |
Disables all pending agents. 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... | |
INTSTATUS | IntWinAgentActivatePendingAgent (void) |
Activates a pending agent that waits to be injected. More... | |
void | IntWinAgentInit (void) |
Initialize the agents state. More... | |
INTSTATUS | IntWinAgentUnInit (void) |
Uninit the agents state. More... | |
#define AG_OPT_INJECT_ON_RIP_POWSTATE_CHANGE 0x00000001 |
This flag is used for injecting the PT Filter/VE unloader directly from the NtSetSystemPowerState hook handler WARNING: do not use outside of the NtSetSystemPowerState callback (winpower.c) as it might have some unexpected results.
Definition at line 17 of file winagent.h.
Referenced by IntWinAgentActivatePendingAgent(), IntWinAgentHandleLoader1Hypercall(), IntWinAgentRemove(), and IntWinPowHandleEventCommon().
#define MAX_BOOTSTRAP_SIZE 512u |
Maximum size of the bootstrap code.
Definition at line 12 of file winagent.h.
Referenced by IntWinAgentInject().
typedef enum _AGENT_HCALL AGENT_HCALL |
Agent hyper call types.
typedef INTSTATUS(* PFUNC_AgentCompletion) (QWORD GuestVirtualAddress, DWORD ErrorCode, DWORD AgentTag, void *Context) |
Completion callback.
Completion callback. This callback is called after the in-guest agent boot driver has finished execution. Note that this callback is not called when the agent process, for example finishes execution; it is called when the trampoline, bootstrap code and the boot driver all finished their job (which may be the delivery of a file, or starting a process). In order to see when an injected processes finished execution, look after process termination events generated by that process.
[in] | GuestVirtualAddress | Guest virtual address where the boot driver has been injected. |
[in] | ErrorCode | The injection error code. If anything fails inside the guest, this ErrorCode will capture the failure information (for example, that a process could not be started). |
[in] | AgentTag | The agent tag, as provided to the IntWinAgentInject function. |
[in] | Context | Optional context, as passed to the IntWinAgentInject function. |
Definition at line 56 of file winagent.h.
Called for VE and PT initialization.
This callback is called when the boot driver issues a specific hypercall; right now, this is reserved for the VE and PT drivers only, and it is used to do the their initialization or to free them, on unload. If someone needs special handling during agent injection, it can use this callback, as it can do any custom work when invoked by the boot driver.
[in] | GuestVirtualAddress | Guest virtual address where the boot driver has been injected. |
[in] | MaxSize | A generic memory size, if anything was allocated by the boot driver. |
[in] | Context | Optional context, as passed to the IntWinAgentInject function. |
Definition at line 77 of file winagent.h.
typedef INTSTATUS(* PFUNC_AgentInjection) (QWORD GuestVirtualAddress, DWORD AgentTag, void *Context) |
Injection callback.
Injection callback. Once the bootstrap allocates the agent memory, this callback will be invoked. It should inject the actual code and data for the agent. The reason why a callback is used for this is because we might need the virtual address of the buffer to do some pre-processing (like applying the relocations, in case of a PE executable).
[in] | GuestVirtualAddress | Guest virtual address where the boot driver has been injected. |
[in] | AgentTag | The agent tag, as provided to the IntWinAgentInject function. |
[in] | Context | Optional context, as passed to the IntWinAgentInject function. |
Definition at line 33 of file winagent.h.
typedef struct _WIN_AGENT * PWIN_AGENT |
typedef struct _WIN_AGENT WIN_AGENT |
Describes one agent running inside the guest.
enum _AGENT_HCALL |
Agent hyper call types.
Enumerator | |
---|---|
AGENT_HCALL_VMCALL | Hyper call using VMCALL. |
AGENT_HCALL_INT3 | Hyper call using INT3. |
Definition at line 87 of file winagent.h.
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().
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().
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().
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().
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().
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().
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().