This repository has been archived by the owner on Nov 17, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 23
/
profile.c
109 lines (87 loc) · 2.78 KB
/
profile.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <r_lib.h>
#include "profile.h"
static addr_t get_kernel_base(vmi_instance_t vmi, json_object *root)
{
addr_t kernel_base;
status_t status;
// get $CONSTANTS
json_object* constants = NULL;
if (!json_object_object_get_ex(root, "$CONSTANTS", &constants))
goto outerr;
// get PsActiveProcessHead
json_object* process_head = NULL;
if (!json_object_object_get_ex(constants, "PsActiveProcessHead", &process_head))
goto outerr;
// get PsActiveProcessHead rva;
addr_t process_head_rva = json_object_get_int64(process_head);
// translate PsActiveProcessHead with vmi_translate
addr_t process_head_addr;
status = vmi_translate_ksym2v(vmi, "PsActiveProcessHead", &process_head_addr);
if (status == VMI_FAILURE)
goto outerr;
// get kernel base address
kernel_base = process_head_addr - process_head_rva;
return kernel_base;
outerr:
eprintf("Fail to get kernel base\n");
return 0;
}
static bool load_symbols_section(RIO *io, json_object *root,
const char *section_name, addr_t kernel_base)
{
json_object* section = NULL;
if (!json_object_object_get_ex(root, section_name, §ion))
goto outerr;
addr_t symbol_addr;
char cmd[2048];
json_object_object_foreach(section, key, val) {
// skip symbols starting with str:
if (!strncmp(key, "str:", strlen("str:")))
continue;
// skip symbols containing an @
if (strchr(key, '@'))
continue;
symbol_addr = kernel_base + json_object_get_int64(val);
// printf("symbol: %s, addr: 0x%lx\n", key, symbol_addr);
bzero(cmd, 2048);
snprintf(cmd, 2048, "f rekall.%s = 0x%lx\n", key, symbol_addr);
io->cb_printf(cmd);
}
return true;
outerr:
eprintf("Cannot load section %s\n", section_name);
return false;
}
bool load_symbols(RIO *io, vmi_instance_t vmi)
{
const char* profile_path = NULL;
json_object* root = NULL;
addr_t kernel_base;
// get rekall profile
profile_path = vmi_get_rekall_path(vmi);
if (!profile_path)
{
eprintf("Libvmi config has no Rekall profile path\n");
return false;
}
// load as json
root = json_object_from_file(profile_path);
if (!root)
goto outerr;
// get kernel base
kernel_base = get_kernel_base(vmi, root);
if (!kernel_base)
goto outerr;
if (!load_symbols_section(io, root, "$CONSTANTS", kernel_base))
goto outerr;
if (!load_symbols_section(io, root, "$FUNCTIONS", kernel_base))
goto outerr;
if (root)
json_object_put(root);
return true;
outerr:
eprintf("Error while parsing JSON Rekall profile\n");
if (root)
json_object_put(root);
return false;
}