Bitdefender Hypervisor Memory Introspection
detours.h File Reference

The guest detour API. More...

#include "thread_safeness.h"
#include "handlers.h"

Go to the source code of this file.

Data Structures

struct  _DETOUR_ARGS
 Describes the arguments passed by a in-guest detour handler to introcore. More...
 
struct  _API_HOOK_PUBLIC_DATA
 Public data which allows for external modification to a in-guest hook handler. More...
 
struct  _API_HOOK_HANDLER
 Described a detour handler. More...
 
struct  _API_HOOK_DESCRIPTOR
 Describes a function to be hooked. More...
 
struct  _LIX_FN_DETOUR
 Describes a Linux-function to be hooked. More...
 
struct  _DETOUR
 Describes a detour set inside the guest memory. More...
 

Macros

#define DET_ARG_REGS(Arg)   (gGuest.Guest64 ? ((DWORD)(Arg) < 16) : ((DWORD)(Arg) < 8))
 Checks if the argument should be taken from the guest general purpose registers. More...
 
#define DET_ARG_STACK(Index)   (((DWORD)(Index) << 16) | 0xFFFF)
 Creates an encoding for a parameter passed on the guest stack. More...
 
#define DET_ARG_ON_STACK(Arg)   (((Arg) & 0xFFFF) == 0xFFFF)
 Checks if the argument should be taken from the guest stack. More...
 
#define DET_ARG_STACK_OFFSET(Arg)   (((Arg) >> 16) * gGuest.WordSize)
 Gets the stack offset at which a stack argument is found. More...
 
#define DET_ARGS_MAX   8
 The maximum number of arguments passed from the guest to introcore. More...
 
#define DET_ARGS_DEFAULT_LIX
 Default argument passing convention for Linux guests. More...
 
#define DET_ARGS_DEFAULT_WIN64
 Default argument passing convention for 64-bit Windows guests. More...
 
#define DET_ARGS_DEFAULT_WIN86
 Default argument passing convention for 32-bit Windows guests. More...
 
#define DETOUR_MAX_HANDLER_SIZE   512
 The maximum size of a in-guest detour handler. More...
 
#define DETOUR_MAX_HANDLERS   8
 The maximum number of handlers a detour can have. More...
 
#define PUBLIC_DATA_MAX_NAME_SIZE   16
 The maximum size of the PublicDataName field inside the API_HOOK_PUBLIC_DATA structure. More...
 
#define PUBLIC_DATA_MAX_DESCRIPTORS   5
 The maximum number of entries in the PublicDataOffsets array inside the API_HOOK_HANDLER structure. More...
 
#define DETOUR_MIN_VERSION_ANY   0
 Specifies that the first OS version for which a detour handler is available is the first OS version supported by introcore. More...
 
#define DETOUR_MAX_VERSION_ANY   0xFFFFFFFF
 Specifies that the first OS version for which a detour handler is available is the latest OS version supported by introcore. More...
 
#define DETOUR_INVALID_HYPERCALL   0xFF
 Used to specify that no hypercall is present in the detour handler so the HypercallOffset field inside the API_HOOK_HANDLER is not valid. More...
 
#define DETOUR_ENABLE_ALWAYS   0xFFFFFFFFFFFFFFFF
 Can be used as the API_HOOK_DESCRIPTOR.EnableFlags to always enable the detour. More...
 

Typedefs

typedef struct _LIX_FN_DETOUR LIX_FN_DETOUR
 Describes a Linux-function to be hooked. More...
 
typedef struct _DETOUR_ARGS DETOUR_ARGS
 Describes the arguments passed by a in-guest detour handler to introcore. More...
 
typedef INTSTATUS(* PFUNC_DetourCallback) (void *Detour)
 The type of a detour callback. More...
 
typedef INTSTATUS(* PFUNC_PreDetourCallback) (QWORD FunctionAddress, void *Handler, void *Descriptor)
 The type of a callback invoked before setting a detour. More...
 
typedef INTSTATUS(* PFUNC_PostDetourCallback) (void *Handler)
 The type of a callback invoked after a detour is set. More...
 
typedef struct _API_HOOK_PUBLIC_DATA API_HOOK_PUBLIC_DATA
 Public data which allows for external modification to a in-guest hook handler. More...
 
typedef struct _API_HOOK_PUBLIC_DATAPAPI_HOOK_PUBLIC_DATA
 
typedef struct _API_HOOK_HANDLER API_HOOK_HANDLER
 Described a detour handler. More...
 
typedef struct _API_HOOK_HANDLERPAPI_HOOK_HANDLER
 
typedef struct _WIN_UNEXPORTED_FUNCTION WIN_UNEXPORTED_FUNCTION
 
typedef struct _API_HOOK_DESCRIPTOR API_HOOK_DESCRIPTOR
 Describes a function to be hooked. More...
 
typedef struct _API_HOOK_DESCRIPTORPAPI_HOOK_DESCRIPTOR
 
typedef INTSTATUS(* PFUNC_LixDetourCallback) (void *Detour)
 The type of a linux-detour callback. More...
 
typedef struct _DETOUR DETOUR
 Describes a detour set inside the guest memory. More...
 
typedef struct _DETOURPDETOUR
 

Enumerations

enum  DETOUR_TAG {
  detTagUnknown = 0, detTagPoolAlloc, detTagPoolFree, detTagModuleLoad,
  detTagModuleUnload, detTagProcCreate, detTagProcTerminate, detTagProcInject,
  detTagProcPtrace, detTagProcPtraceCompat, detTagProcVmRw, detTagEarlyProt,
  detTagBugcheck, detTagBugcheck2, detTagSyscallHook, detTagProcCopy,
  detTagException, detTagVadInsert, detTagVadInsertPriv, detTagVadInsertMap,
  detTagVmProtect, detTagVaDelete, detTagFinishVadDeletion, detTagVadDelete,
  detTagVadDeletePartial, detTagUnmapSection, detTagVadAdjust, detTagVadExpandDown,
  detTagPowerState, detTagProcThrHijack, detTagProcThrHijackWow64, detTagTextPoke,
  detTagTextPoke2, detTagProcQueueApc, detTagCommitCreds, detTagProbeKernelWrite,
  detTagSwapgs, detTagAccessRemoteVm, detTagSetProcInformation, detTagRtlVirtualUnwind1,
  detTagRtlVirtualUnwind2, detTagRtlVirtualUnwind3, detTagRtlVirtualUnwind4, detTagRtlVirtualUnwind5,
  detTagRtlVirtualUnwind6, detTagRtlVirtualUnwind7, detTagRtlVirtualUnwind8, detTagRtlVirtualUnwindMax,
  detTagCleanupMemDump, detTagVadCommit, detTagKernelRead, detTagProcSwapIn,
  detTagProcSwapOut, detTagMax
}
 Unique tag used to identify a detour. More...
 
enum  HYPERCALL_TYPE { hypercallTypeNone = 0, hypercallTypeInt3, hypercallTypeVmcall }
 The type of the hypercall used by a detour. More...
 

Functions

INTSTATUS IntDetSetHook (QWORD FunctionAddress, QWORD ModuleBase, API_HOOK_DESCRIPTOR *Descriptor, API_HOOK_HANDLER *Handler)
 Will inject code inside the guest. More...
 
INTSTATUS IntDetSetLixHook (QWORD FunctionAddress, const LIX_FN_DETOUR *FnDetour, BOOLEAN *MultipleInstructions)
 Detours a function from guest. More...
 
INTSTATUS IntDetSetReturnValue (DETOUR const *Detour, IG_ARCH_REGS *Registers, QWORD ReturnValue)
 Sets the return value for a hooked guest function. More...
 
INTSTATUS IntDetCallCallback (void)
 Calls the appropriate detour handler for hypercall. More...
 
INTSTATUS IntDetEnableDetour (DETOUR_TAG Tag)
 Enables a detour based on its tag. More...
 
INTSTATUS IntDetDisableDetour (DETOUR_TAG Tag)
 Disables a detour based on its tag. More...
 
void IntDetDisableAllHooks (void)
 Removes all detours from the guest. More...
 
void IntDetUninit (void)
 Uninitializes the detour module. More...
 
void IntDetDumpDetours (void)
 Prints all the detours in the gDetours list of detours. More...
 
BOOLEAN IntDetIsPtrInHandler (QWORD Ptr, THS_PTR_TYPE Type, DETOUR_TAG *Tag)
 Checks if a guest pointer is inside a detour handler. More...
 
BOOLEAN IntDetIsPtrInRelocatedCode (QWORD Ptr, DETOUR_TAG *Tag)
 Checks if a guest pointer is inside the modified prologue of a function. More...
 
QWORD IntDetRelocatePtrIfNeeded (QWORD Ptr)
 Returns the new value Ptr should have if it is currently pointing inside a relocated prologue. More...
 
INTSTATUS IntDetGetAddrAndTag (QWORD Ptr, QWORD *Address, DWORD *Size, DETOUR_TAG *Tag)
 Checks if Ptr is inside a detour handler and returns the detour's handler address, size and tag. More...
 
INTSTATUS IntDetGetByTag (DETOUR_TAG Tag, QWORD *Address, DWORD *Size)
 Get a detour handler address and size by its tag. More...
 
INTSTATUS IntDetGetArgument (void const *Detour, DWORD Index, BYTE const *StackBuffer, DWORD StackBufferSize, QWORD *Value)
 Reads the specified argument for a detour. More...
 
INTSTATUS IntDetGetArguments (void const *Detour, DWORD Argc, QWORD *Argv)
 Reads multiple arguments from a detour. More...
 
INTSTATUS IntDetPatchArgument (void const *Detour, DWORD Index, QWORD Value)
 Modifies the value of a detour argument. More...
 
INTSTATUS IntDetModifyPublicData (DETOUR_TAG Tag, void const *Data, DWORD DataSize, char const *PublicDataName)
 Modifies public parts of a detour handler. More...
 
INTSTATUS IntDetGetFunctionAddressByTag (DETOUR_TAG Tag, QWORD *FunctionAddress)
 Get a detour function address by its tag. More...
 

Detailed Description

The guest detour API.

Definition in file detours.h.

Macro Definition Documentation

◆ DET_ARG_ON_STACK

#define DET_ARG_ON_STACK (   Arg)    (((Arg) & 0xFFFF) == 0xFFFF)

Checks if the argument should be taken from the guest stack.

Parameters
[in]ArgThe argument encoding as taken from a DETOUR_ARGS structure.
Returns
True if the argument is present on the guest stack; False if it is not. If the argument is present on the stack, DET_ARG_STACK_OFFSET should be used to obtain its stack offset.

Definition at line 57 of file detours.h.

Referenced by IntDetGetArgumentInternal(), IntDetGetArguments(), and IntDetPatchArgument().

◆ DET_ARG_REGS

#define DET_ARG_REGS (   Arg)    (gGuest.Guest64 ? ((DWORD)(Arg) < 16) : ((DWORD)(Arg) < 8))

Checks if the argument should be taken from the guest general purpose registers.

Parameters
[in]ArgThe argument encoding as taken from a DETOUR_ARGS structure.
Returns
True if the argument is present in the guest GPRs; False if it is not. If the argument is present in the guest GPRs, Arg will be the register index.

Definition at line 39 of file detours.h.

Referenced by IntDetGetArgumentInternal(), and IntDetPatchArgument().

◆ DET_ARG_STACK

#define DET_ARG_STACK (   Index)    (((DWORD)(Index) << 16) | 0xFFFF)

Creates an encoding for a parameter passed on the guest stack.

In order to distinguish stack arguments from arguments passed through registers, the lower word of the argument is set to 0xFFFF, while the upper word is the stack index.

Parameters
[in]IndexThe parameter index on the stack (parameter 1 has index 1, parameter 2 has index 2, etc).
Returns
An encoding for the given parameter index.

Definition at line 49 of file detours.h.

◆ DET_ARG_STACK_OFFSET

#define DET_ARG_STACK_OFFSET (   Arg)    (((Arg) >> 16) * gGuest.WordSize)

Gets the stack offset at which a stack argument is found.

DET_ARG_ON_STACK must be used in order to check that the argument is present on the stack before using this macro.

Parameters
[in]ArgThe argument encoding as taken from a DETOUR_ARGS structure.
Returns
The offset, relative to the current guest RSP, at which the argument is found.

Definition at line 66 of file detours.h.

Referenced by IntDetGetArgumentInternal(), IntDetGetArguments(), and IntDetPatchArgument().

◆ DET_ARGS_DEFAULT_LIX

#define DET_ARGS_DEFAULT_LIX
Value:
{.Argc = DET_ARGS_MAX, .Argv = {NDR_RDI, NDR_RSI, NDR_RDX, NDR_RCX, \
NDR_R8, NDR_R9, DET_ARG_STACK(1), DET_ARG_STACK(2)}}
#define DET_ARG_STACK(Index)
Creates an encoding for a parameter passed on the guest stack.
Definition: detours.h:49
#define DET_ARGS_MAX
The maximum number of arguments passed from the guest to introcore.
Definition: detours.h:69

Default argument passing convention for Linux guests.

Definition at line 72 of file detours.h.

◆ DET_ARGS_DEFAULT_WIN64

#define DET_ARGS_DEFAULT_WIN64
Value:
{.Argc = DET_ARGS_MAX, .Argv = {NDR_RCX, NDR_RDX, NDR_R8, NDR_R9, \
DET_ARG_STACK(5), DET_ARG_STACK(6), DET_ARG_STACK(7), DET_ARG_STACK(8)}}
#define DET_ARG_STACK(Index)
Creates an encoding for a parameter passed on the guest stack.
Definition: detours.h:49
#define DET_ARGS_MAX
The maximum number of arguments passed from the guest to introcore.
Definition: detours.h:69

Default argument passing convention for 64-bit Windows guests.

This follows the default calling convention used on 64-bit Windows and takes into consideration the stack shadow space, so indexes 1, 2, 3, and 4 point to the shadow space. See https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2019

Definition at line 80 of file detours.h.

◆ DET_ARGS_DEFAULT_WIN86

#define DET_ARGS_DEFAULT_WIN86
Value:
{.Argc = DET_ARGS_MAX, \
DET_ARG_STACK(5), DET_ARG_STACK(6), DET_ARG_STACK(7), DET_ARG_STACK(8)}}
#define DET_ARG_STACK(Index)
Creates an encoding for a parameter passed on the guest stack.
Definition: detours.h:49
#define DET_ARGS_MAX
The maximum number of arguments passed from the guest to introcore.
Definition: detours.h:69

Default argument passing convention for 32-bit Windows guests.

This follows cdecl calling convention. See https://docs.microsoft.com/en-us/cpp/cpp/cdecl?view=vs-2019

Definition at line 86 of file detours.h.

◆ DET_ARGS_MAX

#define DET_ARGS_MAX   8

The maximum number of arguments passed from the guest to introcore.

Definition at line 69 of file detours.h.

Referenced by IntDetGetArgument(), and IntDetGetArguments().

◆ DETOUR_ENABLE_ALWAYS

#define DETOUR_ENABLE_ALWAYS   0xFFFFFFFFFFFFFFFF

Can be used as the API_HOOK_DESCRIPTOR.EnableFlags to always enable the detour.

Definition at line 429 of file detours.h.

Referenced by IntWinApiUpdateHooks().

◆ DETOUR_INVALID_HYPERCALL

#define DETOUR_INVALID_HYPERCALL   0xFF

Used to specify that no hypercall is present in the detour handler so the HypercallOffset field inside the API_HOOK_HANDLER is not valid.

Definition at line 321 of file detours.h.

Referenced by IntDetCallCallback(), IntDetDisableWinHypercall(), IntDetEnableHypercall(), and IntDetSetHook().

◆ DETOUR_MAX_HANDLER_SIZE

#define DETOUR_MAX_HANDLER_SIZE   512

The maximum size of a in-guest detour handler.

Definition at line 194 of file detours.h.

Referenced by IntDetRelocate(), and IntDetSetHook().

◆ DETOUR_MAX_HANDLERS

#define DETOUR_MAX_HANDLERS   8

The maximum number of handlers a detour can have.

Definition at line 195 of file detours.h.

◆ DETOUR_MAX_VERSION_ANY

#define DETOUR_MAX_VERSION_ANY   0xFFFFFFFF

Specifies that the first OS version for which a detour handler is available is the latest OS version supported by introcore.

Definition at line 317 of file detours.h.

◆ DETOUR_MIN_VERSION_ANY

#define DETOUR_MIN_VERSION_ANY   0

Specifies that the first OS version for which a detour handler is available is the first OS version supported by introcore.

Definition at line 314 of file detours.h.

◆ PUBLIC_DATA_MAX_DESCRIPTORS

#define PUBLIC_DATA_MAX_DESCRIPTORS   5

The maximum number of entries in the PublicDataOffsets array inside the API_HOOK_HANDLER structure.

Definition at line 257 of file detours.h.

◆ PUBLIC_DATA_MAX_NAME_SIZE

#define PUBLIC_DATA_MAX_NAME_SIZE   16

The maximum size of the PublicDataName field inside the API_HOOK_PUBLIC_DATA structure.

Definition at line 255 of file detours.h.

Typedef Documentation

◆ API_HOOK_DESCRIPTOR

Describes a function to be hooked.

This is used by IntDetSetHook and IntDetSetLixHook to know what to hook and how to find the hooked region.

◆ API_HOOK_HANDLER

Described a detour handler.

◆ API_HOOK_PUBLIC_DATA

Public data which allows for external modification to a in-guest hook handler.

This allows for changes to be made only to certain parts of the detour handler, delimited by the PublicDataOffset and PublicDataSize fields.

◆ DETOUR

typedef struct _DETOUR DETOUR

Describes a detour set inside the guest memory.

This is created by IntDetSetHook and IntDetSetLixHook in order to hold information about a detour that has been set. Part of the information in this structure comes from the API_HOOK_DESCRIPTOR used for this hook.

◆ DETOUR_ARGS

typedef struct _DETOUR_ARGS DETOUR_ARGS

Describes the arguments passed by a in-guest detour handler to introcore.

These definitions help describe argument passing between the handler injected by introcore inside the guest and the detour handler invoked inside introcore. These can match the way the guest passes the arguments, but the handler inside the guest can change this order and can also obtain additional information, so these do not describe any in-guest calling convention. Arguments can be passed either in the guest general purpose registers, or on the stack. The argument is always encoded in a 32-bit integer. In the case in which arguments are passed through the guest GPRs, the argument is encoded as the index of the register which holds it. The index respects the order defined by Intel docs and can be seen in the IG_ARCH_REGS structure. For arguments passed on the stack, the lower word of the index is set to 0xFFFF and the upper word is the index on the stack. In other words, the first parameter is encoded as 0x1FFFF, the second parameter is encoded as 0x2FFFF and so on. This closely follows the way parameters are passed on the stack, stack[0] being the return address, stack[1] the first parameter and so on. We pass only integers or guest pointers.

◆ LIX_FN_DETOUR

typedef struct _LIX_FN_DETOUR LIX_FN_DETOUR

Describes a Linux-function to be hooked.

Definition at line 31 of file detours.h.

◆ PAPI_HOOK_DESCRIPTOR

◆ PAPI_HOOK_HANDLER

◆ PAPI_HOOK_PUBLIC_DATA

◆ PDETOUR

typedef struct _DETOUR * PDETOUR

◆ PFUNC_DetourCallback

typedef INTSTATUS(* PFUNC_DetourCallback) (void *Detour)

The type of a detour callback.

This is the type of the function that will be invoked when a detour handler issues a hypercall.

Parameters
[in]DetourThe detour handle. This is an opaque value for the handler; it can be used by other detour APIs.
Return values
INT_STATUS_DISABLE_DETOUR_ON_RETif the detour should be disabled after the callback returns.
INT_STATUS_REMOVE_DETOUR_AND_SET_RIPif the detour should be removed from the guest. This will set the guest RIP back to the start of the hooked code region in order to let the guest properly execute the code. This does not work if the hypercall type is not hypercallTypeInt3.
INT_STATUS_SUCCESSin case of success. While all status values beside INT_STATUS_DISABLE_DETOUR_ON_RET and INT_STATUS_REMOVE_DETOUR_AND_SET_RIP are ignored, it is good practice to actually return a success status value in no error was encountered.

Definition at line 212 of file detours.h.

◆ PFUNC_LixDetourCallback

typedef INTSTATUS(* PFUNC_LixDetourCallback) (void *Detour)

The type of a linux-detour callback.

This is the type of the function that will be invoked when a detour handler issues a hypercall.

Parameters
[in]DetourThe detour handle. This is an opaque value for the handler; it can be used by other detour APIs.
Return values
INT_STATUS_DISABLE_DETOUR_ON_RETif the detour should be disabled after the callback returns.
INT_STATUS_REMOVE_DETOUR_AND_SET_RIPif the detour should be removed from the guest. This will set the guest RIP back to the start of the hooked code region in order to let the guest properly execute the code. This does not work if the hypercall type is not hypercallTypeInt3.
INT_STATUS_SUCCESSin case of success. While all status values beside INT_STATUS_DISABLE_DETOUR_ON_RET and INT_STATUS_REMOVE_DETOUR_AND_SET_RIP are ignored, it is good practice to actually return a success status value in no error was encountered.

Definition at line 408 of file detours.h.

◆ PFUNC_PostDetourCallback

typedef INTSTATUS(* PFUNC_PostDetourCallback) (void *Handler)

The type of a callback invoked after a detour is set.

This is an optional callback. If one exists, it will be invoked as the last step of the detour setting process, after everything has been written inside the guest memory.

Parameters
[in]HandlerPointer to a API_HOOK_HANDLER structure.
Returns
INT_STATUS_SUCCESS if successful, or an appropriate INTSTATUS error value; if an error is returned, it will be logged but no special action will be taken. More importantly, the detour will not be disabled or removed if an error is returned.

Definition at line 250 of file detours.h.

◆ PFUNC_PreDetourCallback

typedef INTSTATUS(* PFUNC_PreDetourCallback) (QWORD FunctionAddress, void *Handler, void *Descriptor)

The type of a callback invoked before setting a detour.

This is an optional callback. If one exists, it will be invoked before any modifications are done to the guest code.

Parameters
[in]FunctionAddressThe guest virtual address of the hooked function.
[in]HandlerOptional pointer to a API_HOOK_HANDLER structure.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
Return values
INT_STATUS_SUCCESSin case of success
INT_STATUS_NOT_NEEDED_HINTif the detour should not be set anymore. This will make the detour mechanism skip the hook and free any resources acquired so far for this detour. Returning an error status has the same effect, but should be avoided if no actual error was encountered, as the error will fail introcore initialization if the detour is marked as being critical.

Definition at line 232 of file detours.h.

◆ WIN_UNEXPORTED_FUNCTION

Definition at line 323 of file detours.h.

Enumeration Type Documentation

◆ DETOUR_TAG

enum DETOUR_TAG

Unique tag used to identify a detour.

See gLixHookHandlersx64, gHookableApisX86, or gHookableApisX64.

Enumerator
detTagUnknown 
detTagPoolAlloc 
detTagPoolFree 
detTagModuleLoad 
detTagModuleUnload 
detTagProcCreate 
detTagProcTerminate 
detTagProcInject 
detTagProcPtrace 
detTagProcPtraceCompat 
detTagProcVmRw 
detTagEarlyProt 
detTagBugcheck 
detTagBugcheck2 
detTagSyscallHook 
detTagProcCopy 
detTagException 
detTagVadInsert 
detTagVadInsertPriv 
detTagVadInsertMap 
detTagVmProtect 
detTagVaDelete 
detTagFinishVadDeletion 
detTagVadDelete 
detTagVadDeletePartial 
detTagUnmapSection 
detTagVadAdjust 
detTagVadExpandDown 
detTagPowerState 
detTagProcThrHijack 
detTagProcThrHijackWow64 
detTagTextPoke 
detTagTextPoke2 
detTagProcQueueApc 
detTagCommitCreds 
detTagProbeKernelWrite 
detTagSwapgs 
detTagAccessRemoteVm 
detTagSetProcInformation 
detTagRtlVirtualUnwind1 
detTagRtlVirtualUnwind2 
detTagRtlVirtualUnwind3 
detTagRtlVirtualUnwind4 
detTagRtlVirtualUnwind5 
detTagRtlVirtualUnwind6 
detTagRtlVirtualUnwind7 
detTagRtlVirtualUnwind8 
detTagRtlVirtualUnwindMax 
detTagCleanupMemDump 
detTagVadCommit 
detTagKernelRead 
detTagProcSwapIn 
detTagProcSwapOut 
detTagMax 

Must always be the last one.

Definition at line 119 of file detours.h.

◆ HYPERCALL_TYPE

The type of the hypercall used by a detour.

Enumerator
hypercallTypeNone 

No hypercall. This detour does not generate events.

hypercallTypeInt3 

The detour will use a INT3 instruction in order to notify introcore about an event.

hypercallTypeVmcall 

The detour will use a VMCALL instruction in order to notify introcore about an event.

Definition at line 184 of file detours.h.

Function Documentation

◆ IntDetCallCallback()

INTSTATUS IntDetCallCallback ( void  )

Calls the appropriate detour handler for hypercall.

This will iterate the list of detours and will call the first one that matches the hypercall. In order to match a detour must have the same hypercall type as the hypercall that was issued, must have the HypercallAddress equal to the RIP from which the hypercall was issued, and must have a valid callback. If it is not disabled, it is called. Even if it is disabled the search stops after the first match.

If the detour is enabled, its HitCount is incremented. If the callback returns INT_STATUS_DISABLE_DETOUR_ON_RET the hypercall is disabled, but the detour is not removed from the guest memory and it will still be executed by the guest. If it returns INT_STATUS_REMOVE_DETOUR_AND_SET_RIP the detour is removed from the guest (this is available only for detours with a hypercallTypeInt3 hypercall type). Other return values are ignored and are not even logged.

Return values
INT_STATUS_SUCCESSin case of success. This does not take into account error encountered by the detour callback.
INT_STATUS_NOT_FOUNDif no matching detour was found. This means that the hypercall was not issued by a detour.
INT_STATUS_NO_DETOUR_EMUif no emulation is needed. This means that the detour callback returned INT_STATUS_REMOVE_DETOUR_AND_SET_RIP and the detour was removed and the guest RIP was moved to point back to the original function address, meaning that the guest should be let to execute the original function, and emulation is not needed, because there is nothing to emulate.

Definition at line 1596 of file detours.c.

Referenced by IntHandleBreakpoint(), and IntHandleIntroCall().

◆ IntDetDisableAllHooks()

void IntDetDisableAllHooks ( void  )

Removes all detours from the guest.

This will restore the original contents of the hooked functions, will remove the detour handlers, and will free any resources associated with the detours, except the detour structures. No safeness checks are done. If a guest thread is currently running inside a detour handler or returns to it the guest will be left in an unstable state.

Definition at line 1848 of file detours.c.

Referenced by IntGuestPrepareUninit().

◆ IntDetDisableDetour()

INTSTATUS IntDetDisableDetour ( DETOUR_TAG  Tag)

Disables a detour based on its tag.

After the detour is disabled, its handler will no longer issue hypercalls, but it will still be present inside the guest and the guest will still execute it. If it has any side effects, those will still be visible inside the guest.

Parameters
[in]TagThe tag of the detour which will be disabled.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Tag is not less than detTagMax.
INT_STATUS_NOT_NEEDED_HINTif no detour exists for the given tag.

Definition at line 324 of file detours.c.

Referenced by IntWinApiUpdateHooks().

◆ IntDetDumpDetours()

void IntDetDumpDetours ( void  )

Prints all the detours in the gDetours list of detours.

Definition at line 1895 of file detours.c.

Referenced by IntGuestUninit().

◆ IntDetEnableDetour()

INTSTATUS IntDetEnableDetour ( DETOUR_TAG  Tag)

Enables a detour based on its tag.

After the detour is enabled, its handler will start to issue hypercalls.

Parameters
[in]TagThe tag of the detour which will be enabled.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Tag is not less than detTagMax.
INT_STATUS_NOT_NEEDED_HINTif no detour exists for the given tag.

Definition at line 361 of file detours.c.

Referenced by IntWinApiUpdateHooks().

◆ IntDetGetAddrAndTag()

INTSTATUS IntDetGetAddrAndTag ( QWORD  Ptr,
QWORD Address,
DWORD Size,
DETOUR_TAG Tag 
)

Checks if Ptr is inside a detour handler and returns the detour's handler address, size and tag.

Parameters
[in]PtrGuest virtual address to check.
[out]AddressIf Ptr is inside a detour handler, will contain the start of the handler. May be NULL.
[out]SizeIf Ptr is inside a detour handler, will contain the size of the handler. May be NULL.
[out]TagIf Ptr is inside a detour handler, will contain the tag of the detour. May be NULL.
Return values
INT_STATUS_SUCCESSif Ptr is inside a detour handler.
INT_STATUS_NOT_FOUNDif Ptr is not inside a detour handler.

Definition at line 2074 of file detours.c.

Referenced by IntRtlpVirtualUnwindCheckAccess().

◆ IntDetGetArgument()

INTSTATUS IntDetGetArgument ( void const *  Detour,
DWORD  Index,
BYTE const *  StackBuffer,
DWORD  StackBufferSize,
QWORD Value 
)

Reads the specified argument for a detour.

Parameters
[in]DetourThe detour for which to read the argument.
[in]IndexThe number of the argument to read.
[in]StackBufferIf the argument is on the stack and this is not NULL, it will be used instead of reading the argument from the guest memory. If multiple calls are made for the same detour, it is worth it to read the guest stack once and passing it as a buffer to all calls made to this function.
[in]StackBufferSizeThe size of the stack buffer. If the argument is outside the size of the stack buffer, it will be taken directly from the guest memory.
[out]ValueOn success, the value of the argument.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Detour is NULL.
INT_STATUS_INVALID_PARAMETER_2if Index is equal or grater than DET_ARGS_MAX.
INT_STATUS_INVALID_PARAMETER_3if Value is NULL.
INT_STATUS_NOT_INITIALIZEDif the Detour is not properly uninitialized.

Definition at line 2237 of file detours.c.

Referenced by IntDriverUnloadHandler(), IntWinProcHandleTerminate(), IntWinProcSwapIn(), IntWinProcSwapOut(), IntWinVadHandleInsertMap(), IntWinVadHandleInsertPrivate(), and IntWinVadHandleVirtualProtect().

◆ IntDetGetArguments()

INTSTATUS IntDetGetArguments ( void const *  Detour,
DWORD  Argc,
QWORD Argv 
)

Reads multiple arguments from a detour.

Iterates over the arguments in Detour and calls IntDetGetArgumentInternal for each one. If one or more arguments are on the stack, the function will calculate the size of the stack that must be read in order to have access on all of them, and map it a single time, before calling it.

Parameters
[in]DetourThe detour for which to read the arguments.
[in]ArgcThe number of arguments to read.
[out]ArgvOn success, will contain the first Argc arguments from this detour. If the detour has less than Argc arguments, the function stops reading when it reaches the last argument. This buffer should be large enough to contain Argc 64-bit integers, even for 32-bit guests.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Detour is NULL.
INT_STATUS_INVALID_PARAMETER_2if Argc is 0 or not less than DET_ARGS_MAX.
INT_STATUS_INVALID_PARAMETER_3if Argv is NULL.
INT_STATUS_NOT_INITIALIZEDif Detour is not fully initialized yet.
INT_STATUS_INVALID_INTERNAL_STATEif the caller requested more arguments than there are available.

Definition at line 2296 of file detours.c.

Referenced by IntDriverLoadHandler(), IntWinHandleException(), IntWinPoolHandleAlloc(), IntWinPoolHandleFree(), IntWinProcHandleCopyMemory(), IntWinProcHandleCreate(), IntWinProcHandleInstrument(), IntWinThrHandleQueueApc(), IntWinThrHandleThreadHijack(), IntWinVadHandleCommit(), IntWinVadHandleDeleteVaRange(), IntWinVadHandleFinishVadDeletion(), IntWinVadHandleInsert(), and IntWinVadHandleVirtualProtect().

◆ IntDetGetByTag()

INTSTATUS IntDetGetByTag ( DETOUR_TAG  Tag,
QWORD Address,
DWORD Size 
)

Get a detour handler address and size by its tag.

Parameters
[in]TagDetour tag.
[out]AddressOn success, the address of the detour handler.
[out]SizeOn success, the size of the detour handler. May be NULL.
Return values
INT_STATUS_SUCCESSif there is a detour for the given tag.
INT_STATUS_NOT_FOUNDif there is no detour for the given tag.

Definition at line 2110 of file detours.c.

Referenced by IntLixPatchSwapgs().

◆ IntDetGetFunctionAddressByTag()

INTSTATUS IntDetGetFunctionAddressByTag ( DETOUR_TAG  Tag,
QWORD FunctionAddress 
)

Get a detour function address by its tag.

Parameters
[in]TagDetour tag.
[out]FunctionAddressOn success, the address of the function which was detoured.
Return values
INT_STATUS_SUCCESSif there is a detour for the given tag.
INT_STATUS_NOT_FOUNDif there is no detour for the given tag.

Definition at line 2144 of file detours.c.

Referenced by IntWinModIsKernelWriteInjection().

◆ IntDetIsPtrInHandler()

BOOLEAN IntDetIsPtrInHandler ( QWORD  Ptr,
THS_PTR_TYPE  Type,
DETOUR_TAG Tag 
)

Checks if a guest pointer is inside a detour handler.

Parameters
[in]PtrThe guest virtual address to check.
[in]TypeThe type of pointer Ptr is. This is used only for logging purposes.
[out]TagIf Ptr is inside a detour handler, will contain the tag of the detour set for it. May be NULL.
Returns
True if Ptr is inside a detour handler prologue, False if it is not.

Definition at line 1980 of file detours.c.

Referenced by IntThrSafeIsLiveRIPInIntro(), and IntThrSafeIsStackPtrInIntro().

◆ IntDetIsPtrInRelocatedCode()

BOOLEAN IntDetIsPtrInRelocatedCode ( QWORD  Ptr,
DETOUR_TAG Tag 
)

Checks if a guest pointer is inside the modified prologue of a function.

Parameters
[in]PtrThe guest virtual address to check.
[out]TagIf Ptr is inside a modified function prologue, will contain the tag of the detour set for it. May be NULL.
Returns
True if Ptr is inside a modified function prologue, False if it is not.

Definition at line 1942 of file detours.c.

Referenced by IntLixPatchHandler().

◆ IntDetModifyPublicData()

INTSTATUS IntDetModifyPublicData ( DETOUR_TAG  Tag,
void const *  Data,
DWORD  DataSize,
char const *  PublicDataName 
)

Modifies public parts of a detour handler.

A detour that allows for external changes exposes the parts of its handler that can be changed as public data by describing them inside the API_HOOK_HANDLER.PublicDataOffsets array. An external caller only needs the detour tag and the name of the data region that it wants to change. The data is modified using the memory cloaking mechanism, see Memory cloaking.

Parameters
[in]TagThe tag of the detour.
[in]DataBuffer with the new contents of the detour handler.
[in]DataSizeThe size of the Data buffer. Must not be larger than the size of the public data region.
[in]PublicDataNameNULL-terminated string of the public data name. This is case sensitive.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Tag is not less than detTagMax.
INT_STATUS_INVALID_PARAMETER_2if Data is NULL.
INT_STATUS_INVALID_PARAMETER_3if DataSize is 0.
INT_STATUS_INVALID_PARAMETER_4if PublicDataName is NULL.
INT_STATUS_NOT_INITIALIZED_HINTif no detour is found for Tag.
INT_STATUS_NOT_FOUNDif no public data region is found for PublicDataName.
INT_STATUS_INVALID_DATA_SIZEif DataSize is larger than the size of the public data region.

Definition at line 1751 of file detours.c.

Referenced by IntWinAgentActivatePendingAgent(), IntWinAgentHandleLoader1Hypercall(), IntWinAgentRemove(), IntWinPowDisableSpinWait(), and IntWinPowEnableSpinWait().

◆ IntDetPatchArgument()

INTSTATUS IntDetPatchArgument ( void const *  Detour,
DWORD  Index,
QWORD  Value 
)

Modifies the value of a detour argument.

Parameters
[in]DetourThe detour for which to modify the value of an argument.
[in]IndexThe index of the argument.
[in]ValueThe value of the argument. For 32-bit guests, the upper 32-bits of the value are ignored.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_1if Detour is NULL.
INT_STATUS_INVALID_PARAMETER_2if Index is not less than the argument count of the detour.
INT_STATUS_NOT_INITIALIZEDif the Detour is not fully initialized yet.
INT_STATUS_INVALID_INTERNAL_STATEif the argument encoding is corrupted.

Definition at line 2410 of file detours.c.

Referenced by IntWinPoolHandleAlloc().

◆ IntDetRelocatePtrIfNeeded()

QWORD IntDetRelocatePtrIfNeeded ( QWORD  Ptr)

Returns the new value Ptr should have if it is currently pointing inside a relocated prologue.

Parameters
[in]PtrGuest virtual address to check.
Returns
The new Ptr value.

Definition at line 2048 of file detours.c.

Referenced by IntThrSafeMoveReturn(), and IntThrSafeMoveRip().

◆ IntDetSetHook()

INTSTATUS IntDetSetHook ( QWORD  FunctionAddress,
QWORD  ModuleBase,
API_HOOK_DESCRIPTOR Descriptor,
API_HOOK_HANDLER Handler 
)

Will inject code inside the guest.

This function will inject a piece of code (the detour handler) inside the guest virtual address space. This can be used to hook a function, but it is not mandatory for this to be a classic function hook. When hooking a function, it will replace at least the first 5 bytes from FunctionAddress with a jump to the hook handler. At least 5 bytes are replaced because that is the size of the injected jump, but more bytes may be replaced if the instructions over-written inside the guest have a larger total length. The original instructions will be relocated after the detour handler and will be followed by a jump back to the remaining function body. If the original instructions are RIP-relative the function will fail.

In order to find a place for the detour handler inside the module in which the hook function resides, the slack.c functionality is used. If no specific API is hooked, the detour will be placed inside the core guest kernel module.

Memory cloaking (see Memory cloaking) will be used to hide the pieces of code modified and injected during this process.

Errors encountered for Descriptors that have the NotCritical field set to False are treated as fatal errors and introcore will be stopped.

If a pre- or post-hook callback exists in the Descriptor it is called. The pre-hook callback is called before the hook is written inside the guest. If it returns INT_STATUS_NOT_NEEDED_HINT, the hook is no longer set, even if it is a critical hook and this is not treated as an error. If an error is returned, the hook will no longer be set, but if the hook is critical this will be treated as an error to set the hook. The post-hook callback return value is ignored.

A detour successfully set can be found in the gDetours list of detours.

Parameters
[in]FunctionAddressThe guest virtual address of the function to be hooked. Can be 0, in which case no function will be hooked, but the detour will still be injected inside the guest.
[in]ModuleBaseThe guest virtual address of the module in which the detour should be placed. If a function is hooked this should be the module that owns that function. If 0 the kernel module will be used.
[in]DescriptorPointer to a structure that describes the hook and the detour handler.
[in]HandlerThe descriptor of the detour handler to be injected inside the guest.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_INVALID_PARAMETER_3if Descriptor is NULL or if its tag is not less than detTagMax.
INT_STATUS_BUFFER_OVERFLOWif the function hooked is inside the Windows kernel, but its address points outside the kernel buffer.
INT_STATUS_NOT_SUPPORTEDif the function is already hooked. This is detected by checking if the function starts with a 0xE9 (a JMP instruction). This means that we already hooked this function, and hooking it again is an error, or a driver inside the guest hooked it, in which case the kernel can not be trusted and it may be already compromised. The same status value is returned if the total size of the handler (including the relocated instructions) is larger than DETOUR_MAX_HANDLER_SIZE.
INT_STATUS_INSUFFICIENT_RESOURCESif not enough memory is available.

Definition at line 1061 of file detours.c.

Referenced by IntLixPatchSwapgs(), and IntWinApiHook().

◆ IntDetSetLixHook()

INTSTATUS IntDetSetLixHook ( QWORD  FunctionAddress,
const LIX_FN_DETOUR FnDetour,
BOOLEAN MultipleInstructions 
)

Detours a function from guest.

The detours content are injected in guest by the 'init' agent (see IntLixGuestAllocateDeploy). Each detour has one structure of type LIX_GUEST_DETOUR assigned; LIX_GUEST_DETOUR structures is ordered by the DETOUR_ID enum.

The function fetches the LIX_GUEST_DETOUR structure (index-based) and fill the FunctionAddress field with the original function address plus the length of the relocated code.

The EnableFlags is used by each detour (in guest) to check if the hypercall is enabled.

The over-written code from original function is relocated by calling the IntDetRelocate function and the 'JMP' instruction that detours the function is set calling the IntDetPatchFunction function.

Parameters
[in]FunctionAddressThe guest virtual address of the function to be hooked
[in]FnDetourPointer to a structure that describes the hook.
[out]MultipleInstructionsOn success, true if multiple instruction is over-written, otherwise false.
Return values
INT_STATUS_SUCCESSOn success.
INT_STATUS_INVALID_PARAMETER_1If FunctionAddress is invalid.
INT_STATUS_INVALID_PARAMETER_2If FnDetour is invalid.

Definition at line 942 of file detours.c.

Referenced by IntLixApiHook().

◆ IntDetSetReturnValue()

INTSTATUS IntDetSetReturnValue ( DETOUR const *  Detour,
IG_ARCH_REGS Registers,
QWORD  ReturnValue 
)

Sets the return value for a hooked guest function.

This allows introcore to set a specific return value for a hooked guest function. Note that the in-guest handler must be aware of this and must be able to properly handle this, usually by returning early from the hooked guest function.

Parameters
[in]DetourThe detour for which the return value is changed.
[in,out]RegistersThe register state to be used. If NULL, the current register state from the current VCPU will be used.
[in]ReturnValueThe return value. If the detour hypercall type is hypercallTypeInt3 this will be set in the RAX register. If the hypercall type is hypercallTypeVmcall this will be set in the RSI register. Other hypercall types are not supported. For 32-bit guests, the upper 32-bits of the return value are ignored.
Return values
INT_STATUS_SUCCESSin case of success.
INT_STATUS_NOT_SUPPORTEDif the hypercall type is not hypercallTypeInt3 or hypercallTypeVmcall.

Definition at line 1528 of file detours.c.

Referenced by IntLixAccessRemoteVmHandler(), IntLixCrashHandle(), IntLixTaskHandleExec(), IntLixTaskHandlePtrace(), IntLixTaskHandleVmRw(), IntWinProcHandleCopyMemory(), IntWinProcHandleInstrument(), IntWinThrHandleQueueApc(), and IntWinThrHandleThreadHijack().

◆ IntDetUninit()

void IntDetUninit ( void  )

Uninitializes the detour module.

Will iterate over the global detour list in gDetours and will call IntDetRemoveDetour for each detour. After this function returns, gDetours will be completely reset and no active detours will be remaining. No safeness checks are done. If a guest thread is currently running inside a detour handler or returns to it the guest will be left in an unstable state.

Definition at line 1868 of file detours.c.

Referenced by IntGuestUninit().