-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathunflatten.hpp
More file actions
348 lines (289 loc) · 10 KB
/
unflatten.hpp
File metadata and controls
348 lines (289 loc) · 10 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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
* Samsung R&D Poland - Mobile Security Group (srpol.mb.sec@samsung.com)
* C/C++ library for interacting with kflat images
*/
#ifndef UNFLATTEN_HPP
#define UNFLATTEN_HPP
#include <stdio.h>
#include <stdint.h>
/********************************
* Exported types
*******************************/
typedef void* CUnflatten;
typedef void* CUnflattenHeader;
typedef uintptr_t (*get_function_address_t)(const char* fsym);
typedef enum {
// No error
UNFLATTEN_OK = 0,
// Invalid root pointer
UNFLATTEN_INVALID_ROOT_POINTER,
// Invalid argument
UNFLATTEN_INVALID_ARGUMENT,
// Invalid node offset
UNFLATTEN_INVALID_OFFSET,
// Invalid magic in read flattened image
UNFLATTEN_INVALID_MAGIC,
// Invalid pointer fix location
UNFLATTEN_INVALID_FIX_LOCATION,
// Invalid pointer fix destination
UNFLATTEN_INVALID_FIX_DESTINATION,
// Address points to an invalid location
UNFLATTEN_INVALID_ADDRESS_POINTEE,
// No next root pointer available
UNFLATTEN_NO_NEXT_ROOT_POINTER,
// Named root pointer not found
UNFLATTEN_NOT_FOUND_NAMED_ROOT_POINTER,
// FLCTRL is uninitialized
UNFLATTEN_UNINITIALIZED_FLCTRL,
// Index out of range
UNFLATTEN_INDEX_OUT_OF_RANGE,
// Failed to acquire read-lock on input file
UNFLATTEN_FILE_LOCKED,
// Unexpected open_mode
UNFLATTEN_UNEXPECTED_OPEN_MODE,
// Image size differs from header
UNFLATTEN_DIFFERENT_IMAGE_SIZE,
// Size of memory area with header exceeds size of an image
UNFLATTEN_MEMORY_SIZE_BIGGER_THAN_IMAGE,
// Memory fragment does not fit in flatten image
UNFLATTEN_MEMORY_FRAGMENT_DOES_NOT_FIT,
// Truncated file
UNFLATTEN_TRUNCATED_FILE,
// Incompatible version of flattened image
UNFLATTEN_UNSUPPORTED_MAGIC,
// Integer overflow
UNFLATTEN_OVERFLOW,
// Memory allocation failed
UNFLATTEN_ALLOCATION_FAILED,
// Interval extraction failed
UNFLATTEN_INTERVAL_EXTRACTION_FAILED,
// Memory was already fixed and is loaded at the same address as previously
UNFLATTEN_ALREADY_FIXED,
UNFLATTEN_STATUS_MAX,
} UnflattenStatus;
/********************************
* C++ interface
*******************************/
#ifdef __cplusplus
/**
* @brief Due to complicated types dependencies, implementation details
* of UnflattenEngine class are hidden from end user. Use Flatten
* wrapper to conveniently access UnflattenEngine library in applications
*/
class UnflattenEngine;
/**
* @brief User interface for accessing UnflattenEngine library
*
*/
class Unflatten {
class UnflattenEngine* engine;
public:
/**
* @brief construct a new (empty) instance of flatten image
*
* @param level: debug level used for printing info
*/
Unflatten(int level = 0);
/**
* @brief destroy the Unflatten object
*/
~Unflatten();
/**
* @brief load new kflat image from file. This method can be safely
* called multiple times to load one image after another
*
* @param file pointer to opened file with kflat image
* @param gfa optional pointer to function resolving func pointers
* @param continuous_mapping whether to allocate dumped memory as one huge blob
* or as many small malloc objects (second variant is slower, but allows
* for detection of buffer overflows with ASAN)
* @return 0 on success, otherwise error code
*/
UnflattenStatus load(FILE* file, get_function_address_t gfa = NULL, bool continuous_mapping = false);
/**
* @brief Provides information regarding kflat image file
*
* @param file pointer to opened file with kflat image
* @param arg optional parameter to decide whith kflat image part information to provide
* @return 0 on success, otherwise error code
*/
UnflattenStatus info(FILE* file, const char* arg = 0);
/**
* @brief free memory occupied by loaded image. Normally, there's no need
* to invoke this function manually (both destructor and load()) calls
* it already
*/
void unload();
/**
* @brief Mark pointer as freed by some external code. This prevents double frees when image is unloaded.
*
* @param mptr already freed pointer
*/
void mark_freed(void *mptr);
/**
* @brief retrieve the pointer to the next flattened object
*
* @return generic pointer to flattened object
*/
void* get_next_root(void);
/**
* @brief retrieve the pointer to the n-th flattened object
*
* @param idx ID of the object to retrieve from image
* @return generic pointer to requested flattened object
*/
void* get_seq_root(size_t idx);
/**
* @brief retrieve named root pointer
*
* @param name the name of root pointer provided to EXTENDED_ROOT_POINTER macro
* @param size[opt] place where size of flattened object will be stored
* @return generic pointer to named object or NULL in case of an error
*/
void* get_named_root(const char* name, size_t* size);
/**
* @brief Replace all pointers to the provided memory range with a new variable. It can be
* used to replace global variable from image with local copy
*
* @param old_mem pointer to old memory
* @param new_mem pointer to new memory
* @param size size of memory chunked to be replaced
* @return ssize_t number of chunkes replaced or negative value in case of an error
*/
ssize_t replace_variable(void* old_mem, void* new_mem, size_t size);
/**
* @brief Provide description of a given status code
*
* @param status status code
* @return status string description
*/
static const char *explain_status(int8_t status);
};
extern "C" {
#endif
/********************************
* C interface
*******************************/
/**
* @brief Create a new instance of flatten library
*
* @param level log level
* @return CUnflatten instance or NULL in case of an error
*/
CUnflatten unflatten_init(int level);
/**
* @brief Destroy instance of flatten library
*
* @param flatten library instance
*/
void unflatten_deinit(CUnflatten flatten);
/**
* @brief Load new kflat image from file. This method can be safely
* called multiple times without need of using unflatten_unload
*
* @param flatten library instance
* @param file pointer to opened file with kflat image
* @param gfa optional pointer to function resolving func pointers
* @return 0 on success, any other values indicate an error
*/
UnflattenStatus unflatten_load(CUnflatten flatten, FILE* file, get_function_address_t gfa);
/**
* @brief Load new kflat image from file. Works as unflatten_load except that
* loaded image will be stored as one continous blob in memory. Should
* provide better performance, but ASAN won't be able to detect overflows
* in such memory dump.
*
* @param flatten library instance
* @param file pointer to opened file with kflat image
* @param gfa optional pointer to function resolving func pointers
* @return 0 on success, any other values indicate an error
*/
UnflattenStatus unflatten_load_continuous(CUnflatten flatten, FILE* file, get_function_address_t gfa);
/**
* @brief Unload kflat image. Normally, there's no need for invoking this
* function manually - both unflatten_load and unflatten_deinit invokes
* unflatten_unload when necessary
*
* @param flatten library instance
*/
void unflatten_unload(CUnflatten flatten);
/**
* @brief Print information about the flattened image
*
* @param flatten library instance
* @param file pointer to opened file with kflat image
* @return 0 on success, any other values indicate an error
*/
UnflattenStatus unflatten_imginfo(CUnflatten flatten, FILE* file);
/**
* @brief Retrieve the pointer to the next flattened object
*
* @param flatten library instance
* @return generic pointer to flattened object or NULL if an error occurred
*/
void* unflatten_root_pointer_next(CUnflatten flatten);
/**
* @brief Retrieve the pointer to the n-th flattened object
*
* @param flatten library instance
* @param idx ID of object to retrieve from image
* @return generic pointer to flattened object or NULL if an error occurred
*/
void* unflatten_root_pointer_seq(CUnflatten flatten, size_t idx);
/**
* @brief Retrieve the pointer to the named flattened object
*
* @param flatten library instance
* @param name name of the object to retrieve
* @param size[opt] place where the size of target object will be stored
* @return void* generic pointer to the named flattened object or NULL
*/
void* unflatten_root_pointer_named(CUnflatten flatten, const char* name, size_t* size);
/**
* @brief Mark pointer as freed by some external code. This prevents double frees when image is unloaded.
*
* @param flatten library instance
* @param mptr already freed pointer
*/
void unflatten_mark_freed(CUnflatten flatten, void *mptr);
/**
* @brief Retrieve the pointer to the flatten image header structure
*
* @return CUnflattenHeader generic pointer to the flatten image header structure or NULL
*/
CUnflattenHeader unflatten_get_image_header(CUnflatten flatten);
/**
* @brief Retrieve the number of fragments in the flatten memory image
*
* @param header image header instance
* @return unsigned long number of memory fragments in the image
*/
unsigned long unflatten_header_fragment_count(CUnflattenHeader header);
/**
* @brief Retrieve the size of the flatten memory
* @param header image header instance
* @return size_t size of the flatten memory
*/
size_t unflatten_header_memory_size(CUnflattenHeader header);
/**
* @brief Replace all pointers to the provided memory range with new variable. It can be
* used to replace global variable from image with local copy
*
* @param flatten library instance
* @param old_mem pointer to old memory
* @param new_mem pointer to new memory
* @param size size of memory chunked to be replaced
* @return ssize_t number of chunkes replaced or negative value in case of an error
*/
ssize_t unflatten_replace_variable(CUnflatten flatten, void* old_mem, void* new_mem, size_t size);
/**
* @brief Provide description of a given status code
*
* @param status status code
* @return status string description
*/
const char *unflatten_explain_status(int8_t status);
#ifdef __cplusplus
}
#endif
#endif /* UNFLATTEN_HPP */