Bitdefender Hypervisor Memory Introspection
common.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #ifndef _COMMON_H_
6 #define _COMMON_H_
7 
8 #include "handlers.h"
9 
10 #include <stdint.h>
11 #include <signal.h>
12 #include <stddef.h>
13 #include <stdbool.h>
14 #include <errno.h>
15 
16 #define __fn_aligned __attribute__((aligned(16)))
17 #define __fn_save_all __attribute__((no_caller_saved_registers))
18 
19 #define __section(S) __attribute__((section (S)))
20 
21 #define __default_fn_attr __fn_save_all __fn_aligned
22 #define __fn_naked __attribute__((naked))
23 
24 #define BIT(x) (1ULL << (x))
25 #define UNUSED_PARAMETER(P) ((void)(P))
26 #define PAGE_SIZE 0x1000
27 
28 
29 #define get_jump_back_offset(fn_name) \
30  (__builtin_offsetof(LIX_HYPERCALL_PAGE, Detours) \
31  + (det_ ## fn_name) * sizeof(LIX_GUEST_DETOUR) \
32  + __builtin_offsetof(LIX_GUEST_DETOUR, JumpBack))
33 
34 #define get_detour_enable_offset(fn_name) \
35  (__builtin_offsetof(LIX_HYPERCALL_PAGE, Detours) \
36  + (det_ ## fn_name) * sizeof(LIX_GUEST_DETOUR) \
37  + __builtin_offsetof(LIX_GUEST_DETOUR, EnableOptions)) \
38 
39 #define GNUASM_DEFINE_STR(SYMBOL, STR) \
40  asm volatile ("#define " SYMBOL " " #STR);
41 
42 #define GNUASM_DEFINE_VAL(SYMBOL, VALUE) \
43  asm volatile ("#define " SYMBOL " %0" :: "n"(VALUE))
44 
45 #define def_detour_asm_vars(fn_name) \
46  GNUASM_DEFINE_VAL(#fn_name "_jmp", get_jump_back_offset(fn_name))
47 
48 #define def_detour_hijack_asm_vars(fn_name, hijack_fn_name) \
49  GNUASM_DEFINE_VAL(#fn_name "_" # hijack_fn_name "_jmp", get_jump_back_offset(fn_name ## _ ## hijack_fn_name))
50 
51 #define def_detour_vars(fn_name) \
52  extern void *fn_name ## _trampoline; extern void *fn_name ## _reloc
53 
54 #define def_detour_hijack_vars(fn_name, fn_hijack_name) \
55  extern void *fn_name ## _ ## fn_hijack_name ## _trampoline; extern void *fn_name ## _ ## fn_hijack_name ## _reloc
56 #define init_detour_field(fn_name) \
57  [det_ ## fn_name] = { \
58  .Name = #fn_name, \
59  .HijackName[0] = '\0', \
60  .Address = (unsigned long)&fn_name ## _trampoline, \
61  .RelocatedCode = (unsigned long)&fn_name ## _reloc \
62  }
63 
64 #define init_detour_hijack_field(fn_name, hijack_fn_name) \
65  [det_ ## fn_name ## _ ## hijack_fn_name] = { \
66  .Name = #fn_name, \
67  .HijackName = #hijack_fn_name, \
68  .Address = (unsigned long)&fn_name ## _ ## hijack_fn_name ## _trampoline, \
69  .RelocatedCode = (unsigned long)&fn_name ## _ ## hijack_fn_name ## _reloc \
70  }
71 
72 #define __vmcall_param_1(param) \
73  register size_t __p1 asm("r8") = (size_t)(param); asm volatile("" :: "r" (__p1));
74 
75 #define __vmcall_param_2(param) \
76  register size_t __p2 asm("r9") = (size_t)(param); asm volatile("" :: "r" (__p2));
77 
78 #define __vmcall_param_3(param) \
79  register size_t __p3 asm("r10") = (size_t)(param); asm volatile("" :: "r" (__p3));
80 
81 #define __vmcall_param_4(param) \
82  register size_t __p4 asm("r11") = (size_t)(param); asm volatile("" :: "r" (__p4));
83 
84 #define __vmcall_param_5(param) \
85  register size_t __p5 asm("r12") = (size_t)(param); asm volatile("" :: "r" (__p5));
86 
87 #define __vmcall_param_6(param) \
88  register size_t __p6 asm("r13") = (size_t)(param); asm volatile("" :: "r" (__p6));
89 
90 #define __vmcall_param_7(param) \
91  register size_t __p7 asm("r14") = (size_t)(param); asm volatile("" :: "r" (__p7));
92 
93 #define __vmcall_param_8(param) \
94  register size_t __p8 asm("r15") = (size_t)(param); asm volatile("" :: "r" (__p8));
95 
96 
97 #define vmcall_1(id, p1) \
98 ({ \
99  __vmcall_param_1(p1); \
100  vmcall(id); \
101 })
102 
103 
104 #define vmcall_2(id, p1, p2) \
105 ({ \
106  __vmcall_param_1(p1); \
107  __vmcall_param_2(p2); \
108  vmcall(id); \
109 })
110 
111 
112 #define vmcall_3(id, p1, p2, p3) \
113 ({ \
114  __vmcall_param_1(p1); \
115  __vmcall_param_2(p2); \
116  __vmcall_param_3(p3); \
117  vmcall(id); \
118 })
119 
120 
121 #define vmcall_4(id, p1, p2, p3, p4) \
122 ({ \
123  __vmcall_param_1(p1); \
124  __vmcall_param_2(p2); \
125  __vmcall_param_3(p3); \
126  __vmcall_param_4(p4); \
127  vmcall(id); \
128 })
129 
130 
131 #define vmcall_5(id, p1, p2, p3, p4, p5) \
132 ({ \
133  __vmcall_param_1(p1); \
134  __vmcall_param_2(p2); \
135  __vmcall_param_3(p3); \
136  __vmcall_param_4(p4); \
137  __vmcall_param_5(p5); \
138  vmcall(id); \
139 })
140 
141 
142 #define vmcall_6(id, p1, p2, p3, p4, p5, p6) \
143 ({ \
144  __vmcall_param_1(p1); \
145  __vmcall_param_2(p2); \
146  __vmcall_param_3(p3); \
147  __vmcall_param_4(p4); \
148  __vmcall_param_5(p5); \
149  __vmcall_param_6(p6); \
150  vmcall(id); \
151 })
152 
153 #endif // _COMMON_H_