Bitdefender Hypervisor Memory Introspection
run.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Bitdefender
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 #include "../common.h"
6 
7 typedef void * (vmalloc_fn)(unsigned long size);
8 typedef void (vfree_fn)(void *ptr);
9 typedef char ** (argv_split_fn)(unsigned int gfp, const char *str, int *argcp);
10 typedef void (argv_free_fn)(char **argv);
11 typedef void (do_exit_fn)(long code);
12 typedef void *(call_usermodehelper_setup_fn)(const char *path, char **argv, char **envp, unsigned long gfp_mask,
13  int (*init)(void *info, void *new), void (*cleanup)(void *info), void *data);
14 typedef int (call_usermodehelper_exec_fn)(void *sub_info, int wait);
15 typedef int (printk_fn)(const char *fmt, ...);
16 
17 #pragma pack(push, 1)
18 struct data {
20  struct {
21  unsigned long hypercall;
22  unsigned long completion;
23  unsigned long error;
24  } token;
25 
27  struct {
33  vfree_fn *vfree;
35  } func;
36 
38  struct {
39  char commnad[1024];
40 
41  struct {
42  unsigned long wait_proc;
43  unsigned long wait_exec;
44  } umh;
45  } args;
46 };
47 
48 #pragma pack(pop)
49 
51 struct data _data __section(".adata") __aligned(1) = { 0 };
52 
53 extern void *__address;
54 
55 
57 int call_usermodehelper(const char *path, char **argv, char **envp, unsigned int wait)
58 {
59  unsigned long gfp_mask = GFP_KERNEL;
60  void *info = _data.func.call_usermodehelper_setup(path, argv, envp, gfp_mask, NULL, NULL, NULL);
61  if (!info)
62  {
64  return -1;
65  }
66 
67  return _data.func.call_usermodehelper_exec(info, wait);
68 }
69 
71 void run(void)
77 {
78  int ret = 0;
79  char **argv = NULL;
80 
81  char *envp[4];
82 
83  envp[0] = "HOME=/";
84  envp[1] = "TERM=linux";
85  envp[2] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
86  envp[3] = NULL;
87 
88  argv = _data.func.argv_split(GFP_KERNEL, _data.args.commnad, NULL);
89  if (!argv)
90  {
91  breakpoint_2(_data.token.error, _data.func.argv_split, argv);
92  goto _exit;
93  }
94 
95  call_usermodehelper(argv[0], argv, envp, _data.args.umh.wait_exec);
96  if (ret)
97  {
99  goto _exit;
100  }
101 
102  breakpoint(_data.token.completion);
103 
104 _exit:
105  if (argv)
106  {
107  _data.func.argv_free(argv);
108  }
109 }
110 
111 
112 __fn_naked __section(".start")
113 void trampoline(void)
121 {
122  run();
123 
124  __exit;
125  __do_exit(__address, _data.func.do_exit, _data.func.vfree);
126 }
void() do_exit_fn(long code)
Definition: run.c:11
struct data::@2 args
The arguments of the agent.
char **() argv_split_fn(unsigned int gfp, const char *str, int *argcp)
Definition: run.c:9
struct data::@0 token
The tokens used to communicate with Intocore.
__default_fn_attr void run(void)
Creates a new process that execute the provided command line.
Definition: run.c:71
call_usermodehelper_exec_fn * call_usermodehelper_exec
Definition: deploy.c:41
unsigned long hypercall
Definition: kthread.c:17
__default_fn_attr int call_usermodehelper(const char *path, char **argv, char **envp, unsigned int wait)
Definition: run.c:57
char commnad[1024]
The command line to be executed.
Definition: run.c:39
void * __address
static __default_fn_attr unsigned long breakpoint(unsigned long token)
Generate INT3 instruction for hypercall.
Definition: common.h:167
#define GFP_KERNEL
Definition: common.h:15
__fn_naked void trampoline(void)
The trampoline of the agent.
Definition: run.c:113
void() argv_free_fn(char **argv)
Definition: run.c:10
__default_fn_attr void init(void)
Allocates memory for detours and agents.
Definition: init.c:15
call_usermodehelper_setup_fn * call_usermodehelper_setup
Definition: deploy.c:40
#define __fn_naked
Definition: common.h:79
#define __exit
Generates the exit asm-code for agents.
Definition: common.h:120
#define __section(S)
Definition: common.h:76
unsigned long wait_proc
The value of UMH_WAIT_PROC.
Definition: deploy.c:55
#define __default_fn_attr
Definition: common.h:78
#define breakpoint_2(token, p1, p2)
Hypercall using 2 argument.
Definition: common.h:185
int() printk_fn(const char *fmt,...)
Definition: run.c:15
unsigned long wait_exec
The value of UMH_WAIT_EXEC.
Definition: deploy.c:56
struct data::@5::@6 umh
struct data::@1 func
The functions used by this agent.
void *() call_usermodehelper_setup_fn(const char *path, char **argv, char **envp, unsigned long gfp_mask, int(*init)(void *info, void *new), void(*cleanup)(void *info), void *data)
Definition: run.c:12
int() call_usermodehelper_exec_fn(void *sub_info, int wait)
Definition: run.c:14
void *() vmalloc_fn(unsigned long size)
Definition: run.c:7
argv_split_fn * argv_split
Definition: deploy.c:38
unsigned long completion
Definition: kthread.c:18
vfree_fn * vfree
Definition: deploy.c:37
#define __do_exit(address, do_exit_fn, vfree_fn)
Pushes the exit address on the stack and jumps to the 'do_exit' function in order to terminate the th...
Definition: common.h:126
do_exit_fn * do_exit
Definition: deploy.c:42
unsigned long error
Definition: kthread.c:19
void() vfree_fn(void *ptr)
Definition: run.c:8
argv_free_fn * argv_free
Definition: deploy.c:39
Definition: kthread.c:14
printk_fn * printk
Definition: deploy.c:43