-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathintrospection.h
More file actions
217 lines (159 loc) · 5.71 KB
/
introspection.h
File metadata and controls
217 lines (159 loc) · 5.71 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
* libpulp - User-space Livepatching Library
*
* Copyright (C) 2017-2021 SUSE Software Solutions GmbH
*
* This file is part of libpulp.
*
* libpulp is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* libpulp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with libpulp. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _INTROSPECTION_H_
#define _INTROSPECTION_H_
#include <link.h>
#include <stdbool.h>
#include "error_common.h"
#include "ptrace.h"
#include "ulp_common.h"
#include "arch_common.h"
extern int ulp_verbose;
extern int ulp_quiet;
extern bool no_color;
struct trigger_results
{
const char *patch_name;
int err;
struct trigger_results *next;
};
struct ulp_process
{
int pid;
bool all_threads_hijacked;
Elf64_Addr load_bias;
Elf64_Addr dyn_addr;
struct ulp_thread *threads;
struct ulp_thread *main_thread;
struct ulp_dynobj *dynobj_main;
struct ulp_dynobj *dynobj_libpulp;
struct ulp_dynobj *dynobj_targets;
struct ulp_dynobj *dynobj_patches;
unsigned long global_universe;
/** Holds on a trigger many ulps, which patches were applied on the run. */
struct trigger_results *results;
struct ulp_process *next;
};
struct ulp_thread
{
int tid;
registers_t context;
int consistent;
struct ulp_thread *next;
};
struct thread_state
{
int tid;
unsigned long universe;
struct thread_state *next;
};
/** Represents a dynamic object, such as dynamic libraries (.so) or the
* executable itself.
*/
struct ulp_dynobj
{
/** Name of the library. Empty string in case of the executable itself. */
char *filename;
/* Link map, as in _r_debug symbol loaded by the linker. */
struct link_map link_map;
/** Address of dynstr section of current library in the target process. */
Elf64_Addr dynstr_addr;
/** Address of dynsym section of current library in the target process. */
Elf64_Addr dynsym_addr;
/** Number of symbols in the dynsym section of current library in the target
* process. */
int num_symbols;
/** Build id of current library loaded in the target process. */
unsigned char build_id[BUILDID_LEN];
/* FIXME: only libpulp objects should have those symbols. */
Elf64_Addr trigger;
Elf64_Addr check;
Elf64_Addr state;
Elf64_Addr global;
Elf64_Addr msg_queue_old;
Elf64_Addr msg_queue;
Elf64_Addr revert_all;
Elf64_Addr metadata_buffer;
Elf64_Addr error_state;
Elf64_Addr enable_disable_patching;
Elf64_Addr insn_queue;
/* Version of the libpulp tool running on the target process. */
ulp_version_t libpulp_version;
/* Version of the insn_queue on target process. */
int insn_queue_version;
/* end FIXME. */
struct thread_state *thread_states;
/** Next dynobj in the dynobj chain (linked list). */
struct ulp_dynobj *next;
};
struct ulp_addresses
{
Elf64_Addr trigger;
Elf64_Addr path_buffer;
Elf64_Addr check;
Elf64_Addr state;
Elf64_Addr global;
};
void release_ulp_process(struct ulp_process *);
void release_ulp_global_metadata(void);
void release_ulp_reference(struct ulp_reference *);
void release_ulp_dependency(struct ulp_dependency *);
void release_ulp_object(struct ulp_object *unit);
int dig_main_link_map(struct ulp_process *process);
Elf64_Addr get_loaded_symbol_addr_on_disk(struct ulp_dynobj *obj,
const char *sym);
Elf64_Addr get_loaded_symbol_addr(struct ulp_dynobj *obj, int pid,
const char *sym);
int dig_load_bias(struct ulp_process *process);
int parse_main_dynobj(struct ulp_process *process);
int parse_libs_dynobj(struct ulp_process *process);
struct ulp_dynobj *dynobj_first(struct ulp_process *);
struct ulp_dynobj *dynobj_next(struct ulp_process *, struct ulp_dynobj *);
int initialize_data_structures(struct ulp_process *process);
int hijack_threads(struct ulp_process *process);
int set_id_buffer(struct ulp_process *process, unsigned char *patch_id);
int set_path_buffer(struct ulp_process *process, const char *path);
int patch_applied(struct ulp_process *process, unsigned char *id, int *result);
int apply_patch(struct ulp_process *process, void *metadata, size_t size,
bool disable_seccomp_p);
int revert_patches_from_lib(struct ulp_process *, const char *);
int restore_threads(struct ulp_process *process);
int read_global_universe(struct ulp_process *process);
char *extract_ulp_from_so_to_disk(const char *, bool);
size_t extract_ulp_from_so_to_mem(const char *, bool, char **, const char *);
int load_patch_info_from_disk(const char *livepatch);
int load_patch_info_from_mem(void *src, size_t size);
int check_patch_sanity(struct ulp_process *, const char *);
struct ulp_applied_patch *ulp_read_state(struct ulp_process *);
void release_ulp_applied_patch(struct ulp_applied_patch *);
#if defined ENABLE_STACK_CHECK && ENABLE_STACK_CHECK
int coarse_library_range_check(struct ulp_process *process, char *library);
#endif
static inline const char *
get_process_name(struct ulp_process *process)
{
return get_basename(process->dynobj_main->filename);
}
ElfW(Addr) get_ehdr_addr(struct ulp_process *, struct ulp_dynobj *);
ulp_error_t get_libpulp_error_state_remote(struct ulp_process *);
const char *adjust_prefix_for_chroot(struct ulp_process *,
const char *user_prefix);
#endif