Bitdefender Hypervisor Memory Introspection
detours.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _DETOURS_H_
6 #define _DETOURS_H_
7 
21 
27 
28 #include "thread_safeness.h"
29 #include "handlers.h"
30 
32 
39 #define DET_ARG_REGS(Arg) (gGuest.Guest64 ? ((DWORD)(Arg) < 16) : ((DWORD)(Arg) < 8))
40 
49 #define DET_ARG_STACK(Index) (((DWORD)(Index) << 16) | 0xFFFF)
50 
57 #define DET_ARG_ON_STACK(Arg) (((Arg) & 0xFFFF) == 0xFFFF)
58 
66 #define DET_ARG_STACK_OFFSET(Arg) (((Arg) >> 16) * gGuest.WordSize)
67 
69 #define DET_ARGS_MAX 8
70 
72 #define DET_ARGS_DEFAULT_LIX {.Argc = DET_ARGS_MAX, .Argv = {NDR_RDI, NDR_RSI, NDR_RDX, NDR_RCX, \
73  NDR_R8, NDR_R9, DET_ARG_STACK(1), DET_ARG_STACK(2)}}
74 
80 #define DET_ARGS_DEFAULT_WIN64 {.Argc = DET_ARGS_MAX, .Argv = {NDR_RCX, NDR_RDX, NDR_R8, NDR_R9, \
81  DET_ARG_STACK(5), DET_ARG_STACK(6), DET_ARG_STACK(7), DET_ARG_STACK(8)}}
82 
86 #define DET_ARGS_DEFAULT_WIN86 {.Argc = DET_ARGS_MAX, \
87  .Argv = {DET_ARG_STACK(1), DET_ARG_STACK(2), DET_ARG_STACK(3), DET_ARG_STACK(4),\
88  DET_ARG_STACK(5), DET_ARG_STACK(6), DET_ARG_STACK(7), DET_ARG_STACK(8)}}
89 
108 typedef struct _DETOUR_ARGS
109 {
112 } DETOUR_ARGS;
113 
119 typedef enum
120 {
159 
169 
173 
175 } DETOUR_TAG;
176 
180 typedef enum
181 {
189 
190 #define DETOUR_MAX_HANDLER_SIZE 512
191 #define DETOUR_MAX_HANDLERS 8
192 
209  _In_ void *Detour
210  );
211 
229  _In_ QWORD FunctionAddress,
230  _In_ void *Handler,
231  _In_ QWORD HandlerAddress
232  );
233 
247  _In_ void *Handler
248  );
249 
251 #define PUBLIC_DATA_MAX_NAME_SIZE 16
252 #define PUBLIC_DATA_MAX_DESCRIPTORS 5
254 
260 typedef struct _API_HOOK_PUBLIC_DATA
261 {
269 
270 // Handler code. If the NtBuildNumber is zero, the handler can be used for Windows guests with any NtBuildNumber.
271 // If the NtBuildNumber is NOT zero, the handler can be used only for Windows guests that have the exact same
272 // NtBuildNumber. For this reason, the generic handler must be placed the last one: we could have a special handler
273 // for Windows with NtBuildNumber 10000 for example, and a generic handler that works for all other Windows
274 // guests.
275 
279 typedef struct _API_HOOK_HANDLER
280 {
307 
310 #define DETOUR_MIN_VERSION_ANY 0
311 #define DETOUR_MAX_VERSION_ANY 0xFFFFFFFF
314 
317 #define DETOUR_INVALID_HYPERCALL 0xFF
318 
320 
325 typedef struct _API_HOOK_DESCRIPTOR
326 {
348 
386 
387 
403 typedef INTSTATUS
405  _In_ void *Detour
406  );
407 
408 
412 typedef struct _LIX_FN_DETOUR
413 {
415  char *FunctionName;
416  char *HijackFunctionName;
420 } LIX_FN_DETOUR;
421 
422 
423 
425 #define DETOUR_ENABLE_ALWAYS 0xFFFFFFFFFFFFFFFF
426 
432 typedef struct _DETOUR
433 {
438 
441 
448 
457 
460 
463 
474 
479 
488 
495 
497  PAPI_HOOK_DESCRIPTOR Descriptor;
499 } DETOUR, *PDETOUR;
500 
501 
502 INTSTATUS
504  _In_ QWORD FunctionAddress,
505  _In_ QWORD ModuleBase,
506  _Inout_ API_HOOK_DESCRIPTOR *Descriptor,
507  _Inout_ API_HOOK_HANDLER *Handler
508  );
509 
510 INTSTATUS
512  _In_ QWORD FunctionAddress,
513  _In_ const LIX_FN_DETOUR *FnDetour,
514  _Out_ BOOLEAN *MultipleInstructions
515  );
516 
517 INTSTATUS
519  _In_ DETOUR const *Detour,
520  _Inout_opt_ IG_ARCH_REGS *Registers,
521  _In_ QWORD ReturnValue
522  );
523 
524 INTSTATUS
526  void
527  );
528 
529 INTSTATUS
531  _In_ DETOUR_TAG Tag
532  );
533 
534 INTSTATUS
536  _In_ DETOUR_TAG Tag
537  );
538 
539 void
541  void
542  );
543 
544 void
546  void
547  );
548 
549 void
551  void
552  );
553 
554 BOOLEAN
556  _In_ QWORD Ptr,
557  _In_ THS_PTR_TYPE Type,
558  _Out_opt_ DETOUR_TAG *Tag
559  );
560 
561 BOOLEAN
563  _In_ QWORD Ptr,
564  _Out_opt_ DETOUR_TAG *Tag
565  );
566 
567 QWORD
569  _In_ QWORD Ptr
570  );
571 
572 INTSTATUS
574  _In_ QWORD Ptr,
575  _Out_ QWORD *Address,
576  _Out_ DWORD *Size,
577  _Out_ DETOUR_TAG *Tag
578  );
579 
580 INTSTATUS
582  _In_ DETOUR_TAG Tag,
583  _Out_ QWORD *Address,
584  _Out_opt_ DWORD *Size
585  );
586 
587 INTSTATUS
589  _In_ void const *Detour,
590  _In_ DWORD Index,
591  _In_opt_ BYTE const *StackBuffer,
592  _In_ DWORD StackBufferSize,
593  _Out_ QWORD *Value
594  );
595 
596 INTSTATUS
598  _In_ void const *Detour,
599  _In_ DWORD Argc,
600  _Out_writes_(Argc) QWORD *Argv
601  );
602 
603 INTSTATUS
605  _In_ void const *Detour,
606  _In_ DWORD Index,
607  _In_ QWORD Value
608  );
609 
610 INTSTATUS
612  _In_ DETOUR_TAG Tag,
613  _In_ void const *Data,
614  _In_ DWORD DataSize,
615  _In_ char const *PublicDataName
616  );
617 
618 #endif // _DETOURS_H_
uint16_t * PWCHAR
Definition: intro_types.h:63
QWORD LixGuestDetour
The address of the linux-detour header.
Definition: detours.h:459
BOOLEAN IntDetIsPtrInRelocatedCode(QWORD Ptr, DETOUR_TAG *Tag)
Checks if a guest pointer is inside the modified prologue of a function.
Definition: detours.c:1836
#define _In_opt_
Definition: intro_sal.h:16
PWCHAR ModuleName
NULL-terminated string of the kernel module in which the function is found.
Definition: detours.h:328
#define _Out_
Definition: intro_sal.h:22
_Bool BOOLEAN
Definition: intro_types.h:58
QWORD HandlerAddress
The guest virtual address of the detour handler.
Definition: detours.h:450
INTSTATUS IntDetEnableDetour(DETOUR_TAG Tag)
Enables a detour based on its tag.
Definition: detours.c:359
DWORD HandlersCount
The number of valid entries inside the Handlers array.
Definition: detours.h:377
QWORD EnableFlags
Core activation and protection flags that must be set in order to set and activate this hook...
Definition: detours.h:369
BYTE NrPublicDataOffsets
The number of valid entries inside the PublicDataOffsets array.
Definition: detours.h:476
DWORD Argc
The number of valid entries inside the Argv array.
Definition: detours.h:110
struct _API_HOOK_HANDLER * PAPI_HOOK_HANDLER
uint8_t BYTE
Definition: intro_types.h:47
BYTE HypercallOffset
The offset inside the handler at which the hypercall instruction is placed.
Definition: detours.h:299
#define _In_
Definition: intro_sal.h:21
DWORD MaxVersion
The maximum version of the OS for which this handler works.
Definition: detours.h:288
INTSTATUS(* PFUNC_PostDetourCallback)(void *Handler)
The type of a callback invoked after a detour is set.
Definition: detours.h:246
Described a detour handler.
Definition: detours.h:279
QWORD HitCount
The number of times this detour issued a hypercall.
Definition: detours.h:494
Describes a detour set inside the guest memory.
Definition: detours.h:432
DWORD MinVersion
The minimum version of the OS for which this handler works.
Definition: detours.h:284
void IntDetUninit(void)
Uninitializes the detour module.
Definition: detours.c:1762
INTSTATUS IntDetSetReturnValue(DETOUR const *Detour, IG_ARCH_REGS *Registers, QWORD ReturnValue)
Sets the return value for a hooked guest function.
Definition: detours.c:1449
QWORD HypercallAddress
The guest virtual address at which the hypercall is placed.
Definition: detours.h:445
struct _DETOUR_ARGS DETOUR_ARGS
Describes the arguments passed by a in-guest detour handler to introcore.
struct _API_HOOK_PUBLIC_DATA API_HOOK_PUBLIC_DATA
Public data which allows for external modification to a in-guest hook handler.
int INTSTATUS
The status data type.
Definition: introstatus.h:24
struct _DETOUR DETOUR
Describes a detour set inside the guest memory.
QWORD EnableFlags
These are checked against the current options from gGuest.
Definition: detours.h:419
DWORD CodeLength
The size of the handler. Must not be larger than DETOUR_MAX_HANDLER_SIZE.
Definition: detours.h:290
#define DETOUR_MAX_HANDLERS
The maximum number of handlers a detour can have.
Definition: detours.h:191
QWORD DisableFlags
Core activation and protection flags that will cause introcore to skip this hook. ...
Definition: detours.h:363
#define _Out_writes_(expr)
Definition: intro_sal.h:28
The detour will use a INT3 instruction in order to notify introcore about an event.
Definition: detours.h:185
PFUNC_DetourCallback Callback
Callback to be invoked when the detour issues a hypercall. May be NULL.
Definition: detours.h:437
DWORD MaxVersion
The maximum OS version for which this hook should be applied.
Definition: detours.h:341
PFUNC_DetourCallback Callback
Callback to be invoked when the detour issues a hypercall. May be NULL.
Definition: detours.h:343
void * FunctionCloakHandle
The memory cloak handle used to hide the modified function start. See Memory cloaking.
Definition: detours.h:490
No hypercall. This detour does not generate events.
Definition: detours.h:183
#define _Inout_opt_
Definition: intro_sal.h:31
BYTE HypercallOffset
Offset, relative to HandlerAddress, where the hypercall instruction is found.
Definition: detours.h:468
#define _Inout_
Definition: intro_sal.h:20
DETOUR_ARGS Arguments
Encoding of the arguments needed by introcore from the hooked function.
Definition: detours.h:375
#define _Out_opt_
Definition: intro_sal.h:30
DWORD Argv[DET_ARGS_MAX]
Argument encoding. See DET_ARG_REGS and DET_ARG_ON_STACK.
Definition: detours.h:111
INTSTATUS IntDetModifyPublicData(DETOUR_TAG Tag, void const *Data, DWORD DataSize, char const *PublicDataName)
Modifies public parts of a detour handler.
Definition: detours.c:1645
INTSTATUS IntDetGetAddrAndTag(QWORD Ptr, QWORD *Address, DWORD *Size, DETOUR_TAG *Tag)
Checks if Ptr is inside a detour handler and returns the detour&#39;s handler address, size and tag.
Definition: detours.c:1968
Public data which allows for external modification to a in-guest hook handler.
Definition: detours.h:260
INTSTATUS(* PFUNC_PreDetourCallback)(QWORD FunctionAddress, void *Handler, QWORD HandlerAddress)
The type of a callback invoked before setting a detour.
Definition: detours.h:228
unsigned long long QWORD
Definition: intro_types.h:53
PAPI_HOOK_DESCRIPTOR Descriptor
The hook descriptor for which this hook was set.
Definition: detours.h:497
HYPERCALL_TYPE HypercallType
The type of the hypercall that this detour uses.
Definition: detours.h:462
void IntDetDumpDetours(void)
Prints all the detours in the gDetours list of detours.
Definition: detours.c:1789
Must always be the last one.
Definition: detours.h:174
INTSTATUS IntDetSetHook(QWORD FunctionAddress, QWORD ModuleBase, API_HOOK_DESCRIPTOR *Descriptor, API_HOOK_HANDLER *Handler)
Will inject code inside the guest.
Definition: detours.c:985
#define DETOUR_MAX_HANDLER_SIZE
The maximum size of a in-guest detour handler.
Definition: detours.h:190
BOOLEAN IntDetIsPtrInHandler(QWORD Ptr, THS_PTR_TYPE Type, DETOUR_TAG *Tag)
Checks if a guest pointer is inside a detour handler.
Definition: detours.c:1874
INTSTATUS IntDetSetLixHook(QWORD FunctionAddress, const LIX_FN_DETOUR *FnDetour, BOOLEAN *MultipleInstructions)
Detours a function from guest.
Definition: detours.c:874
HYPERCALL_TYPE HypercallType
The type of hypercall used.
Definition: detours.h:292
char * PCHAR
Definition: intro_types.h:56
QWORD FunctionAddress
The guest virtual address of the hooked function.
Definition: detours.h:447
INTSTATUS IntDetGetArgument(void const *Detour, DWORD Index, BYTE const *StackBuffer, DWORD StackBufferSize, QWORD *Value)
Reads the specified argument for a detour.
Definition: detours.c:2105
INTSTATUS IntDetCallCallback(void)
Calls the appropriate detour handler for hypercall.
Definition: detours.c:1517
PFUNC_PostDetourCallback PostCallback
Callback to be invoked after the detour has been set. May be NULL.
Definition: detours.h:347
PFUNC_PreDetourCallback PreCallback
Callback to be invoked before the detour is written inside the guest. May be NULL.
Definition: detours.h:345
Describes a function that is not exported.
Definition: winguest.h:99
HYPERCALL_TYPE
The type of the hypercall used by a detour.
Definition: detours.h:180
DWORD HandlerSize
The size of the detour handler.
Definition: detours.h:456
INTSTATUS IntDetPatchArgument(void const *Detour, DWORD Index, QWORD Value)
Modifies the value of a detour argument.
Definition: detours.c:2278
DWORD MinVersion
The minimum OS version for which this hook should be applied.
Definition: detours.h:337
INTSTATUS IntDetDisableDetour(DETOUR_TAG Tag)
Disables a detour based on its tag.
Definition: detours.c:322
uint32_t DWORD
Definition: intro_types.h:49
INTSTATUS IntDetGetArguments(void const *Detour, DWORD Argc, QWORD *Argv)
Reads multiple arguments from a detour.
Definition: detours.c:2164
LIST_ENTRY Link
The link inside the DETOURS_STATE.DetoursList list.
Definition: detours.h:435
BYTE JumpBackOffset
Offset, relative to HandlerAddress, where the jump that returns control to the hooked function is fou...
Definition: detours.h:466
BOOLEAN Exported
True if this function is exported by the module that owns it.
Definition: detours.h:354
struct _API_HOOK_DESCRIPTOR API_HOOK_DESCRIPTOR
Describes a function to be hooked.
DETOUR_ID Id
The DETOUR_ID of the linux detour descriptor.
Definition: detours.h:414
Describes the arguments passed by a in-guest detour handler to introcore.
Definition: detours.h:108
void IntDetDisableAllHooks(void)
Removes all detours from the guest.
Definition: detours.c:1742
THS_PTR_TYPE
The type of pointer to be checked.
WIN_UNEXPORTED_FUNCTION * Patterns
Array of code patterns used to find this function.
Definition: detours.h:373
QWORD ModuleBase
The guest virtual address of the base of the kernel module that owns the hooked function.
Definition: detours.h:487
BYTE PublicDataOffset
The offset at which the data is available inside the detour handler.
Definition: detours.h:265
BYTE RelocatedCodeLength
The size of the relocated code.
Definition: detours.h:473
void * HandlerCloakHandle
The memory cloak handle used to hide the detour handler. See Memory cloaking.
Definition: detours.h:492
INTSTATUS(* PFUNC_DetourCallback)(void *Detour)
The type of a detour callback.
Definition: detours.h:208
char * FunctionName
Definition: detours.h:415
const LIX_FN_DETOUR * LixFnDetour
Definition: detours.h:498
struct _LIX_FN_DETOUR LIX_FN_DETOUR
Describes a Linux-function to be hooked.
Definition: detours.h:31
BYTE RelocatedCodeOffset
The offset inside the handler at which the original instructions were relocated.
Definition: detours.h:301
BYTE NrPublicDataOffsets
The number of valid entries inside the PublicDataOffsets array.
Definition: detours.h:305
struct _API_HOOK_DESCRIPTOR * PAPI_HOOK_DESCRIPTOR
BOOLEAN NotCritical
If True, this hook is not critical.
Definition: detours.h:358
PFUNC_LixDetourCallback Callback
Callback to be invoked when the detour issues a hypercall.
Definition: detours.h:418
QWORD IntDetRelocatePtrIfNeeded(QWORD Ptr)
Returns the new value Ptr should have if it is currently pointing inside a relocated prologue...
Definition: detours.c:1942
INTSTATUS(* PFUNC_LixDetourCallback)(void *Detour)
The type of a linux-detour callback.
Definition: detours.h:404
BYTE PublicDataSize
The size of the data.
Definition: detours.h:267
Holds register state.
Definition: glueiface.h:30
struct _DETOUR * PDETOUR
DETOUR_TAG
Unique tag used to identify a detour.
Definition: detours.h:119
BOOLEAN Disabled
True if this detour has been disabled.
Definition: detours.h:485
char CHAR
Definition: intro_types.h:56
struct _API_HOOK_PUBLIC_DATA * PAPI_HOOK_PUBLIC_DATA
INTSTATUS IntDetGetByTag(DETOUR_TAG Tag, QWORD *Address, DWORD *Size)
Get a detour handler address and size by its tag.
Definition: detours.c:2004
PCHAR FunctionName
NULL-terminated string of the function name.
Definition: detours.h:333
DETOUR_TAG Tag
Detour tag.
Definition: detours.h:350
BYTE RelocatedCodeOffset
Offset, relative to HandlerAddress, where the prologue that has been replaced by our jump at the begi...
Definition: detours.h:471
struct _API_HOOK_HANDLER API_HOOK_HANDLER
Described a detour handler.
#define DET_ARGS_MAX
The maximum number of arguments passed from the guest to introcore.
Definition: detours.h:69
Describes a function to be hooked.
Definition: detours.h:325
The detour will use a VMCALL instruction in order to notify introcore about an event.
Definition: detours.h:187
DETOUR_TAG Tag
Detour tag.
Definition: detours.h:440
#define PUBLIC_DATA_MAX_NAME_SIZE
The maximum size of the PublicDataName field inside the API_HOOK_PUBLIC_DATA structure.
Definition: detours.h:251
DETOUR_ID
Definition: handlers.h:10
Describes a Linux-function to be hooked.
Definition: detours.h:412
#define PUBLIC_DATA_MAX_DESCRIPTORS
The maximum number of entries in the PublicDataOffsets array inside the API_HOOK_HANDLER structure...
Definition: detours.h:253