Bitdefender Hypervisor Memory Introspection
lixaghnd.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "lixagent.h"
6 #include "guests.h"
7 
10 #include "linux/run/run_content.h"
13 
14 //
15 // Init
16 //
18 {
19  .Allocate =
20  {
21  .ModuleLength = PAGE_SIZE * 3,
22  .PerCpuLength = 0x0,
23  },
24 };
25 
27 {
28  {
29  .Version =
30  {
31  .Sublevel = WORD_MAX,
32  .Patch = BYTE_MAX,
33  .Backport = WORD_MAX,
34  .Version = BYTE_MAX
35  },
36 
37  .Count = 3,
38  .List =
39  {
40  { .Required = 1, .Count = 1, .Name = { "module_alloc"} },
41  { .Required = 1, .Count = 1, .Name = { "change_page_attr_set_clr"} },
42  { .Required = 1, .Count = 1, .Name = { "vmalloc"} },
43  }
44  }
45 };
46 
47 
48 //
49 // Uninit
50 //
52 {
53  .Free =
54  {
55  .ModuleAddress = 0x0,
56  .PerCpuAddress = 0x0,
57  }
58 };
59 
61 {
62  {
63  .Version =
64  {
65  .Sublevel = WORD_MAX,
66  .Patch = BYTE_MAX,
67  .Backport = WORD_MAX,
68  .Version = BYTE_MAX
69  },
70 
71  .Count = 2,
72  .List =
73  {
74  { .Required = 1, .Count = 1, .Name = { "vfree"} },
75  { .Required = 1, .Count = 1, .Name = { "change_page_attr_set_clr"} },
76  }
77  }
78 };
79 
80 
81 //
82 // Create thread
83 //
85 {
86  .Allocate =
87  {
88  .Length = 2 * PAGE_SIZE,
89  }
90 };
91 
92 
94 {
95  {
96  .Version =
97  {
98  .Sublevel = WORD_MAX,
99  .Patch = BYTE_MAX,
100  .Backport = WORD_MAX,
101  .Version = BYTE_MAX
102  },
103 
104  .Count = 3,
105  .List =
106  {
107  { .Required = 1, .Count = 1, .Name = { "kthread_create_on_node"} },
108  { .Required = 1, .Count = 1, .Name = { "wake_up_process"} },
109  { .Required = 1, .Count = 2, .Name = { "vmalloc_exec", "__vmalloc_node_range" } },
110  }
111  }
112 };
113 
114 
115 
116 //
117 // Deploy file
118 //
120 {
121  .Allocate =
122  {
124  },
125 
126  .FilePath =
127  {
128  .Root = '/',
129  .Name = { 0 }
130  }
131 };
132 
133 
135 {
136  {
137  .Version =
138  {
139  .Sublevel = WORD_MAX,
140  .Patch = BYTE_MAX,
141  .Backport = WORD_MAX,
142  .Version = BYTE_MAX
143  },
144 
145  .Count = 11,
146  .List =
147  {
148  { .Required = 1, .Count = 1, .Name = { "filp_open"} },
149  { .Required = 1, .Count = 1, .Name = { "filp_close"} },
150  { .Required = 1, .Count = 2, .Name = { "kernel_write", "__kernel_write"} },
151  { .Required = 1, .Count = 1, .Name = { "vmalloc" } },
152  { .Required = 1, .Count = 1, .Name = { "vfree" } },
153  { .Required = 1, .Count = 1, .Name = { "argv_split" } },
154  { .Required = 1, .Count = 1, .Name = { "argv_free" } },
155  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_setup" } },
156  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_exec" } },
157  { .Required = 1, .Count = 1, .Name = { "do_exit" } },
158  { .Required = 1, .Count = 1, .Name = { "printk" } },
159  }
160  }
161 };
162 
163 
164 //
165 // Deploy file and execute
166 //
168 {
169  .Allocate =
170  {
172  },
173 
174  .FilePath =
175  {
176  .Root = '/',
177  .Name = { 0 }
178  },
179 
180  .Exec =
181  {
182  .Args = { 0x0 }
183  },
184 };
185 
186 
188 {
189  .Exec =
190  {
191  .Args = { 0x0 }
192  },
193 };
194 
195 
197 {
198  {
199  .Version =
200  {
201  .Sublevel = WORD_MAX,
202  .Patch = BYTE_MAX,
203  .Backport = WORD_MAX,
204  .Version = BYTE_MAX
205  },
206 
207  .Count = 13,
208  .List =
209  {
210  { .Required = 1, .Count = 1, .Name = { "filp_open"} },
211  { .Required = 1, .Count = 1, .Name = { "filp_close"} },
212  { .Required = 0, .Count = 1, .Name = { "flush_delayed_fput"} },
213  { .Required = 1, .Count = 2, .Name = { "kernel_write", "__kernel_write"} },
214  { .Required = 1, .Count = 1, .Name = { "vmalloc" } },
215  { .Required = 1, .Count = 1, .Name = { "vfree" } },
216  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_setup" } },
217  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_exec" } },
218  { .Required = 1, .Count = 1, .Name = { "argv_split" } },
219  { .Required = 1, .Count = 1, .Name = { "argv_free" } },
220  { .Required = 1, .Count = 1, .Name = { "do_exit" } },
221  { .Required = 0, .Count = 1, .Name = { "chmod_common" } },
222  { .Required = 1, .Count = 1, .Name = { "printk" } },
223  }
224  }
225 };
226 
227 
229 {
230  {
231  .Version =
232  {
233  .Sublevel = WORD_MAX,
234  .Patch = BYTE_MAX,
235  .Backport = WORD_MAX,
236  .Version = BYTE_MAX
237  },
238 
239  .Count = 7,
240  .List =
241  {
242  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_setup" } },
243  { .Required = 1, .Count = 1, .Name = { "call_usermodehelper_exec" } },
244  { .Required = 1, .Count = 1, .Name = { "argv_split" } },
245  { .Required = 1, .Count = 1, .Name = { "argv_free" } },
246  { .Required = 1, .Count = 1, .Name = { "do_exit" } },
247  { .Required = 1, .Count = 1, .Name = { "vfree" } },
248  { .Required = 1, .Count = 1, .Name = { "printk" } },
249  }
250  }
251 };
252 
253 
254 //
255 // Linux agent-thread handlers
256 //
258 {
259  {
261  .HypercallType = lixAgentHypercallInt3,
262 
263  .Functions =
264  {
265  .Count = ARRAYSIZE(gLixAgentFunctionsDeployFile),
266  .Content = gLixAgentFunctionsDeployFile
267  },
268 
269  .Args =
270  {
271  .Length = sizeof(gLixAgentThreadArgsDeployFile),
272  .Content = &gLixAgentThreadArgsDeployFile
273  },
274 
275  .Code =
276  {
277  .Length = sizeof(gLixAgentDeploy),
278  .Content = gLixAgentDeploy
279  },
280  },
281 
282  {
284  .HypercallType = lixAgentHypercallInt3,
285 
286  .Functions =
287  {
288  .Count = ARRAYSIZE(gLixAgentFunctionsDeployFileExec),
289  .Content = gLixAgentFunctionsDeployFileExec
290  },
291 
292  .Args =
293  {
294  .Length = sizeof(gLixAgentArgsDeployFileExec),
295  .Content = &gLixAgentArgsDeployFileExec
296  },
297 
298  .Code =
299  {
300  .Length = sizeof(gLixAgentExec),
301  .Content = gLixAgentExec
302  },
303  },
304 
305  {
307  .HypercallType = lixAgentHypercallInt3,
308 
309  .Functions =
310  {
311  .Count = ARRAYSIZE(gLixAgentFunctionsRunCommand),
312  .Content = gLixAgentFunctionsRunCommand
313  },
314 
315  .Args =
316  {
317  .Length = sizeof(gLixAgentArgsRunCommand),
318  .Content = &gLixAgentArgsRunCommand
319  },
320 
321  .Code =
322  {
323  .Length = sizeof(gLixAgentRun),
324  .Content = gLixAgentRun
325  },
326  }
327 };
328 
329 
330 //
331 // Linux agent handlers
332 //
334 {
335  {
336  .Tag = lixAgTagInit,
337  .HypercallType = lixAgentHypercallInt3,
338 
339  .Functions =
340  {
341  .Count = ARRAYSIZE(gLixAgentFunctionsInit),
342  .Content = gLixAgentFunctionsInit
343  },
344 
345  .Args =
346  {
347  .Length = sizeof(gLixAgentArgsInit),
348  .Content = &gLixAgentArgsInit
349  },
350 
351  .Code =
352  {
353  .Length = sizeof(gLixAgentInit),
354  .Content = gLixAgentInit
355  }
356  },
357 
358  {
359  .Tag = lixAgTagUninit,
360  .HypercallType = lixAgentHypercallInt3,
361 
362  .Functions =
363  {
364  .Count = ARRAYSIZE(gLixAgentFunctionsUninit),
365  .Content = gLixAgentFunctionsUninit
366  },
367 
368  .Args =
369  {
370  .Length = sizeof(gLixAgentArgsUninit),
371  .Content = &gLixAgentArgsUninit
372  },
373 
374  .Code =
375  {
376  .Length = sizeof(gLixAgentUninit),
377  .Content = gLixAgentUninit
378  }
379  },
380 
381  {
382  .Tag = lixAgTagCreateThread,
383  .HypercallType = lixAgentHypercallInt3,
384 
385  .Functions =
386  {
387  .Count = ARRAYSIZE(gLixAgentFunctionsCreateTread),
388  .Content = gLixAgentFunctionsCreateTread
389  },
390 
391  .Args =
392  {
393  .Length = sizeof(gLixAgentArgsCreateThread),
394  .Content = &gLixAgentArgsCreateThread
395  },
396 
397  .Threads =
398  {
399  .Count = ARRAYSIZE(gLixAgentThreadHandlers),
400  .Content = gLixAgentThreadHandlers
401  }
402  }
403 };
404 
405 
406 
409  _In_ LIX_AGENT_TAG AgentTag
410  )
418 {
419  for (DWORD index = 0; index < ARRAYSIZE(gLixAgentHandler); index++)
420  {
421  if (gLixAgentHandler[index].Tag == AgentTag)
422  {
423  return &gLixAgentHandler[index];
424  }
425  }
426 
427  return NULL;
428 }
429 
430 
433  _In_ LIX_AGENT_TAG AgentTag,
434  _In_ LIX_AGENT_TAG ThreadTag
435  )
444 {
445  LIX_AGENT_HANDLER *pHandler = NULL;
446 
447  pHandler = IntLixAgentGetHandlerByTag(AgentTag);
448  if (pHandler == NULL)
449  {
450  return NULL;
451  }
452 
453  if (pHandler->Threads.Content == NULL)
454  {
455  return NULL;
456  }
457 
458  for (DWORD index = 0; index < pHandler->Threads.Count; index++)
459  {
460  if (pHandler->Threads.Content[index].Tag == ThreadTag)
461  {
462  return &pHandler->Threads.Content[index];
463  }
464  }
465 
466  return NULL;
467 }
468 
469 
LIX_AGENT_UNINIT_ARGS gLixAgentArgsUninit
Definition: lixaghnd.c:51
Describes a handlers that contains the data required by the agent.
Definition: lixagent.h:217
QWORD ModuleLength
The module memory allocation size.
Definition: lixagent.h:259
char Args[LIX_AGENT_MAX_ARGS_LENGTH]
The command line to be executed.
Definition: lixagent.h:366
LIX_AGENT_THREAD_RUN_CLI_ARGS gLixAgentArgsRunCommand
Definition: lixaghnd.c:187
QWORD ModuleAddress
The address of the allocated memory (module).
Definition: lixagent.h:272
LIX_AGENT_THREAD_DEPLOY_FILE_ARGS gLixAgentThreadArgsDeployFile
Definition: lixaghnd.c:119
#define _In_
Definition: intro_sal.h:21
LIX_AGENT_HANDLER * IntLixAgentGetHandlerByTag(LIX_AGENT_TAG AgentTag)
Iterates through all agent handlers and search the entry that has the provided tag.
Definition: lixaghnd.c:408
enum _LIX_AGENT_TAG LIX_AGENT_TAG
Tag used to identify an agent with a handler.
Arguments of the run command-line agent.
Definition: lixagent.h:362
unsigned char gLixAgentUninit[]
Definition: uninit_content.h:1
struct _LIX_AGENT_THREAD_DEPLOY_FILE_EXEC_ARGS::@112 Allocate
LIX_AGENT_FUNCTIONS gLixAgentFunctionsInit[]
Definition: lixaghnd.c:26
Hypercall using INT3 instruction.
Definition: lixagent.h:49
#define ARRAYSIZE(A)
Definition: introdefs.h:101
Run a custom command.
Definition: lixagent.h:69
LIX_AGENT_FUNCTIONS gLixAgentFunctionsDeployFile[]
Definition: lixaghnd.c:134
Arguments of the exec agent.
Definition: lixagent.h:327
Arguments of the deploy-file agent.
Definition: lixagent.h:299
QWORD Length
The memory allocation size to deploy the provided content; to deploy the file, we use chunks...
Definition: lixagent.h:335
LIX_AGENT_HANDLER gLixAgentThreadHandlers[]
Definition: lixaghnd.c:257
unsigned char gLixAgentInit[]
Definition: init_content.h:1
struct _LIX_AGENT_CREATE_THREAD_ARGS::@108 Allocate
struct _LIX_AGENT_INIT_ARGS::@105 Allocate
LIX_AGENT_CREATE_THREAD_ARGS gLixAgentArgsCreateThread
Definition: lixaghnd.c:84
LIX_AGENT_FUNCTIONS gLixAgentFunctionsCreateTread[]
Definition: lixaghnd.c:93
struct _LIX_AGENT_UNINIT_ARGS::@106 Free
LIX_AGENT_INIT_ARGS gLixAgentArgsInit
Definition: lixaghnd.c:17
LIX_AGENT_FUNCTIONS gLixAgentFunctionsRunCommand[]
Definition: lixaghnd.c:228
QWORD Length
The allocation size of the kthread data.
Definition: lixagent.h:291
enum _LIX_AGENT_TAG Tag
The LIX_AGENT_TAG.
Definition: lixagent.h:219
LIX_AGENT_HANDLER * IntLixAgentThreadGetHandlerByTag(LIX_AGENT_TAG AgentTag, LIX_AGENT_TAG ThreadTag)
Iterates through all thread-agent handlers and search the entry that has the provided tag...
Definition: lixaghnd.c:432
Arguments of the uninit agent.
Definition: lixagent.h:268
unsigned char gLixAgentRun[]
Definition: run_content.h:1
#define PAGE_SIZE
Definition: common.h:70
uint32_t DWORD
Definition: intro_types.h:49
Execute a file (process).
Definition: lixagent.h:68
struct _LIX_AGENT_HANDLER::@104 Threads
LIX_AGENT_THREAD_DEPLOY_FILE_EXEC_ARGS gLixAgentArgsDeployFileExec
Definition: lixaghnd.c:167
LIX_AGENT_HANDLER gLixAgentHandler[]
Definition: lixaghnd.c:333
#define PAGE_SIZE_2M
Definition: pgtable.h:15
struct _LIX_AGENT_THREAD_DEPLOY_FILE_ARGS::@109 Allocate
void * Content
The content of the arguments.
Definition: lixagent.h:225
The functions required by the agent.
Definition: lixagent.h:199
Arguments of the create-thread agent.
Definition: lixagent.h:287
unsigned char gLixAgentExec[]
Definition: exec_content.h:1
DWORD Count
The number of the functions.
Definition: lixagent.h:236
LIX_AGENT_FUNCTIONS gLixAgentFunctionsDeployFileExec[]
Definition: lixaghnd.c:196
The create thread agent.
Definition: lixagent.h:64
The init agent.
Definition: lixagent.h:62
unsigned char gLixAgentDeploy[]
Definition: deploy_content.h:1
Deploy a file.
Definition: lixagent.h:67
QWORD Length
The memory allocation size to deploy the provided content; to deploy the file, we use chunks...
Definition: lixagent.h:306
#define WORD_MAX
Definition: introtypes.h:32
struct _LIX_AGENT_THREAD_RUN_CLI_ARGS::@116 Exec
LIX_AGENT_FUNCTIONS gLixAgentFunctionsUninit[]
Definition: lixaghnd.c:60
#define BYTE_MAX
Definition: introtypes.h:31
Arguments of the init agent.
Definition: lixagent.h:255
The uninit agent.
Definition: lixagent.h:63