1 /* radare - LGPL - Copyright 2019 - pancake, oddcoder, Anton Kochkov */
2 
3 #include <r_anal.h>
4 #include <string.h>
5 #include <sdb.h>
6 #include "base_types.h"
7 
is_type(char * type)8 static char *is_type(char *type) {
9 	char *name = NULL;
10 	if ((name = strstr (type, "=type")) ||
11 		(name = strstr (type, "=struct")) ||
12 		(name = strstr (type, "=union")) ||
13 		(name = strstr (type, "=enum")) ||
14 		(name = strstr (type, "=typedef")) ||
15 		(name = strstr (type, "=func"))) {
16 		return name;
17 	}
18 	return NULL;
19 }
20 
get_type_data(Sdb * sdb_types,const char * type,const char * sname)21 static char *get_type_data(Sdb *sdb_types, const char *type, const char *sname) {
22 	char *key = r_str_newf ("%s.%s", type, sname);
23 	if (!key) {
24 		return NULL;
25 	}
26 	char *members = sdb_get (sdb_types, key, NULL);
27 	free (key);
28 	return members;
29 }
30 
r_anal_remove_parsed_type(RAnal * anal,const char * name)31 R_API void r_anal_remove_parsed_type(RAnal *anal, const char *name) {
32 	r_return_if_fail (anal && name);
33 	Sdb *TDB = anal->sdb_types;
34 	SdbKv *kv;
35 	SdbListIter *iter;
36 	const char *type = sdb_const_get (TDB, name, 0);
37 	if (!type) {
38 		return;
39 	}
40 	int tmp_len = strlen (name) + strlen (type);
41 	char *tmp = malloc (tmp_len + 1);
42 	r_type_del (TDB, name);
43 	if (tmp) {
44 		snprintf (tmp, tmp_len + 1, "%s.%s.", type, name);
45 		SdbList *l = sdb_foreach_list (TDB, true);
46 		ls_foreach (l, iter, kv) {
47 			if (!strncmp (sdbkv_key (kv), tmp, tmp_len)) {
48 				r_type_del (TDB, sdbkv_key (kv));
49 			}
50 		}
51 		ls_free (l);
52 		free (tmp);
53 	}
54 }
55 
r_anal_save_parsed_type(RAnal * anal,const char * parsed)56 R_API void r_anal_save_parsed_type(RAnal *anal, const char *parsed) {
57 	r_return_if_fail (anal && parsed);
58 
59 	// First, if any parsed types exist, let's remove them.
60 	char *type = strdup (parsed);
61 	if (type) {
62 		char *cur = type;
63 		while (1) {
64 			cur = is_type (cur);
65 			if (!cur) {
66 				break;
67 			}
68 			char *name = cur++;
69 			*name = 0;
70 			while (name > type && *(name - 1) != '\n') {
71 				name--;
72 			}
73 			r_anal_remove_parsed_type (anal, name);
74 		}
75 		free (type);
76 	}
77 
78 	// Now add the type to sdb.
79 	sdb_query_lines (anal->sdb_types, parsed);
80 }
81 
typecmp(const void * a,const void * b)82 static int typecmp(const void *a, const void *b) {
83 	return strcmp (a, b);
84 }
85 
r_anal_types_from_fcn(RAnal * anal,RAnalFunction * fcn)86 R_API RList *r_anal_types_from_fcn(RAnal *anal, RAnalFunction *fcn) {
87 	RListIter *iter;
88 	RAnalVar *var;
89 	RList *list = r_anal_var_all_list (anal, fcn);
90 	RList *type_used = r_list_new ();
91 	r_list_foreach (list, iter, var) {
92 		r_list_append (type_used, var->type);
93 	}
94 	RList *uniq = r_list_uniq (type_used, typecmp);
95 	r_list_free (type_used);
96 	return uniq;
97 }
98 
enum_type_case_free(void * e,void * user)99 R_IPI void enum_type_case_free(void *e, void *user) {
100 	(void)user;
101 	RAnalEnumCase *cas = e;
102 	free ((char *)cas->name);
103 }
104 
struct_type_member_free(void * e,void * user)105 R_IPI void struct_type_member_free(void *e, void *user) {
106 	(void)user;
107 	RAnalStructMember *member = e;
108 	free ((char *)member->name);
109 	free ((char *)member->type);
110 }
111 
union_type_member_free(void * e,void * user)112 R_IPI void union_type_member_free(void *e, void *user) {
113 	(void)user;
114 	RAnalUnionMember *member = e;
115 	free ((char *)member->name);
116 	free ((char *)member->type);
117 }
118 
get_enum_type(RAnal * anal,const char * sname)119 static RAnalBaseType *get_enum_type(RAnal *anal, const char *sname) {
120 	r_return_val_if_fail (anal && sname, NULL);
121 
122 	RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ENUM);
123 	if (!base_type) {
124 		return NULL;
125 	}
126 
127 	char *members = get_type_data (anal->sdb_types, "enum", sname);
128 	if (!members) {
129 		goto error;
130 	}
131 
132 	RVector *cases = &base_type->enum_data.cases;
133 	if (!r_vector_reserve (cases, (size_t)sdb_alen (members))) {
134 		goto error;
135 	}
136 
137 	char *cur;
138 	sdb_aforeach (cur, members) {
139 		char *val_key = r_str_newf ("enum.%s.%s", sname, cur);
140 		if (!val_key) {
141 			goto error;
142 		}
143 		const char *value = sdb_const_get (anal->sdb_types, val_key, NULL);
144 		free (val_key);
145 
146 		if (!value) { // if nothing is found, ret NULL
147 			goto error;
148 		}
149 
150 		RAnalEnumCase cas = { .name = strdup (cur), .val = strtol (value, NULL, 16) };
151 
152 		void *element = r_vector_push (cases, &cas); // returns null if no space available
153 		if (!element) {
154 			goto error;
155 		}
156 
157 		sdb_aforeach_next (cur);
158 	}
159 	free (members);
160 
161 	return base_type;
162 
163 error:
164 	free (members);
165 	r_anal_base_type_free (base_type);
166 	return NULL;
167 }
168 
get_struct_type(RAnal * anal,const char * sname)169 static RAnalBaseType *get_struct_type(RAnal *anal, const char *sname) {
170 	r_return_val_if_fail (anal && sname, NULL);
171 
172 	RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_STRUCT);
173 	if (!base_type) {
174 		return NULL;
175 	}
176 
177 	char *sdb_members = get_type_data (anal->sdb_types, "struct", sname);
178 	if (!sdb_members) {
179 		goto error;
180 	}
181 
182 	RVector *members = &base_type->struct_data.members;
183 	if (!r_vector_reserve (members, (size_t)sdb_alen (sdb_members))) {
184 		goto error;
185 	}
186 
187 	char *cur;
188 	sdb_aforeach (cur, sdb_members) {
189 		char *type_key = r_str_newf ("struct.%s.%s", sname, cur);
190 		if (!type_key) {
191 			goto error;
192 		}
193 		char *values = sdb_get (anal->sdb_types, type_key, NULL);
194 		free (type_key);
195 
196 		if (!values) {
197 			goto error;
198 		}
199 		char *offset = NULL;
200 		char *type = sdb_anext (values, &offset);
201 		if (!offset) { // offset is missing, malformed state
202 			free (values);
203 			goto error;
204 		}
205 		offset = sdb_anext (offset, NULL);
206 		RAnalStructMember cas = {
207 			.name = strdup (cur),
208 			.type = strdup (type),
209 			.offset = strtol (offset, NULL, 10)
210 		};
211 
212 		free (values);
213 
214 		void *element = r_vector_push (members, &cas); // returns null if no space available
215 		if (!element) {
216 			goto error;
217 		}
218 
219 		sdb_aforeach_next (cur);
220 	}
221 	free (sdb_members);
222 
223 	return base_type;
224 
225 error:
226 	r_anal_base_type_free (base_type);
227 	free (sdb_members);
228 	return NULL;
229 }
230 
get_union_type(RAnal * anal,const char * sname)231 static RAnalBaseType *get_union_type(RAnal *anal, const char *sname) {
232 	r_return_val_if_fail (anal && sname, NULL);
233 
234 	RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_UNION);
235 	if (!base_type) {
236 		return NULL;
237 	}
238 
239 	char *sdb_members = get_type_data (anal->sdb_types, "union", sname);
240 	if (!sdb_members) {
241 		goto error;
242 	}
243 
244 	RVector *members = &base_type->union_data.members;
245 	if (!r_vector_reserve (members, (size_t)sdb_alen (sdb_members))) {
246 		goto error;
247 	}
248 
249 	char *cur;
250 	sdb_aforeach (cur, sdb_members) {
251 		char *type_key = r_str_newf ("union.%s.%s", sname, cur);
252 		if (!type_key) {
253 			goto error;
254 		}
255 		char *values = sdb_get (anal->sdb_types, type_key, NULL);
256 		free (type_key);
257 
258 		if (!values) {
259 			goto error;
260 		}
261 		char *value = sdb_anext (values, NULL);
262 		RAnalUnionMember cas = { .name = strdup (cur), .type = strdup (value) };
263 		free (values);
264 
265 		void *element = r_vector_push (members, &cas); // returns null if no space available
266 		if (!element) {
267 			goto error;
268 		}
269 
270 		sdb_aforeach_next (cur);
271 	}
272 	free (sdb_members);
273 
274 	return base_type;
275 
276 error:
277 	r_anal_base_type_free (base_type);
278 	free (sdb_members);
279 	return NULL;
280 }
281 
get_typedef_type(RAnal * anal,const char * sname)282 static RAnalBaseType *get_typedef_type(RAnal *anal, const char *sname) {
283 	r_return_val_if_fail (anal && R_STR_ISNOTEMPTY (sname), NULL);
284 
285 	RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_TYPEDEF);
286 	if (!base_type) {
287 		return NULL;
288 	}
289 
290 	base_type->type = get_type_data (anal->sdb_types, "typedef", sname);
291 	if (!base_type->type) {
292 		goto error;
293 	}
294 	return base_type;
295 
296 error:
297 	r_anal_base_type_free (base_type);
298 	return NULL;
299 }
300 
get_atomic_type(RAnal * anal,const char * sname)301 static RAnalBaseType *get_atomic_type(RAnal *anal, const char *sname) {
302 	r_return_val_if_fail (anal && R_STR_ISNOTEMPTY (sname), NULL);
303 
304 	RAnalBaseType *base_type = r_anal_base_type_new (R_ANAL_BASE_TYPE_KIND_ATOMIC);
305 	if (!base_type) {
306 		return NULL;
307 	}
308 
309 	base_type->type = get_type_data (anal->sdb_types, "type", sname);
310 	if (!base_type->type) {
311 		goto error;
312 	}
313 
314 	RStrBuf key;
315 	base_type->size = sdb_num_get (anal->sdb_types, r_strbuf_initf (&key, "type.%s.size", sname), 0);
316 	r_strbuf_fini (&key);
317 
318 	return base_type;
319 
320 error:
321 	r_anal_base_type_free (base_type);
322 	return NULL;
323 }
324 
325 // returns NULL if name is not found or any failure happened
r_anal_get_base_type(RAnal * anal,const char * name)326 R_API RAnalBaseType *r_anal_get_base_type(RAnal *anal, const char *name) {
327 	r_return_val_if_fail (anal && name, NULL);
328 
329 	char *sname = r_str_sanitize_sdb_key (name);
330 	const char *type = sdb_const_get (anal->sdb_types, sname, NULL);
331 	if (!type) {
332 		free (sname);
333 		return NULL;
334 	}
335 
336 	RAnalBaseType *base_type = NULL;
337 	if (!strcmp (type, "struct")) {
338 		base_type = get_struct_type (anal, sname);
339 	} else if (!strcmp (type, "enum")) {
340 		base_type = get_enum_type (anal, sname);
341 	} else if (!strcmp (type, "union")) {
342 		base_type = get_union_type (anal, sname);
343 	} else if (!strcmp (type, "typedef")) {
344 		base_type = get_typedef_type (anal, sname);
345 	} else if (!strcmp (type, "type")) {
346 		base_type = get_atomic_type (anal, sname);
347 	}
348 
349 	if (base_type) {
350 		base_type->name = sname;
351 	} else {
352 		free (sname);
353 	}
354 
355 	return base_type;
356 }
357 
save_struct(const RAnal * anal,const RAnalBaseType * type)358 static void save_struct(const RAnal *anal, const RAnalBaseType *type) {
359 	r_return_if_fail (anal && type && type->name
360 		&& type->kind == R_ANAL_BASE_TYPE_KIND_STRUCT);
361 	char *kind = "struct";
362 	/*
363 		C:
364 		struct name {type param1; type param2; type paramN;};
365 		Sdb:
366 		name=struct
367 		struct.name=param1,param2,paramN
368 		struct.name.param1=type,0,0
369 		struct.name.param2=type,4,0
370 		struct.name.paramN=type,8,0
371 	*/
372 	char *sname = r_str_sanitize_sdb_key (type->name);
373 	// name=struct
374 	sdb_set (anal->sdb_types, sname, kind, 0);
375 
376 	RStrBuf arglist;
377 	RStrBuf param_key;
378 	RStrBuf param_val;
379 	r_strbuf_init (&arglist);
380 	r_strbuf_init (&param_key);
381 	r_strbuf_init (&param_val);
382 
383 	int i = 0;
384 	RAnalStructMember *member;
385 	r_vector_foreach (&type->struct_data.members, member) {
386 		// struct.name.param=type,offset,argsize
387 		char *member_sname = r_str_sanitize_sdb_key (member->name);
388 		sdb_set (anal->sdb_types,
389 			r_strbuf_setf (&param_key, "%s.%s.%s", kind, sname, member_sname),
390 			r_strbuf_setf (&param_val, "%s,%zu,%d", member->type, member->offset, 0), 0ULL);
391 		free (member_sname);
392 
393 		r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", member->name);
394 	}
395 	// struct.name=param1,param2,paramN
396 	char *key = r_str_newf ("%s.%s", kind, sname);
397 	sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
398 	free (key);
399 
400 	free (sname);
401 
402 	r_strbuf_fini (&arglist);
403 	r_strbuf_fini (&param_key);
404 	r_strbuf_fini (&param_val);
405 }
406 
save_union(const RAnal * anal,const RAnalBaseType * type)407 static void save_union(const RAnal *anal, const RAnalBaseType *type) {
408 	r_return_if_fail (anal && type && type->name
409 		&& type->kind == R_ANAL_BASE_TYPE_KIND_UNION);
410 	const char *kind = "union";
411 	/*
412 	C:
413 	union name {type param1; type param2; type paramN;};
414 	Sdb:
415 	name=union
416 	union.name=param1,param2,paramN
417 	union.name.param1=type,0,0
418 	union.name.param2=type,0,0
419 	union.name.paramN=type,0,0
420 	*/
421 	char *sname = r_str_sanitize_sdb_key (type->name);
422 	// name=union
423 	sdb_set (anal->sdb_types, sname, kind, 0);
424 
425 	RStrBuf arglist;
426 	RStrBuf param_key;
427 	RStrBuf param_val;
428 	r_strbuf_init (&arglist);
429 	r_strbuf_init (&param_key);
430 	r_strbuf_init (&param_val);
431 
432 	int i = 0;
433 	RAnalUnionMember *member;
434 	r_vector_foreach (&type->union_data.members, member) {
435 		// union.name.arg1=type,offset,argsize
436 		char *member_sname = r_str_sanitize_sdb_key (member->name);
437 		sdb_set (anal->sdb_types,
438 			r_strbuf_setf (&param_key, "%s.%s.%s", kind, sname, member_sname),
439 			r_strbuf_setf (&param_val, "%s,%zu,%d", member->type, member->offset, 0), 0ULL);
440 		free (member_sname);
441 
442 		r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", member->name);
443 	}
444 	// union.name=arg1,arg2,argN
445 	char *key = r_str_newf ("%s.%s", kind, sname);
446 	sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
447 	free (key);
448 
449 	free (sname);
450 
451 	r_strbuf_fini (&arglist);
452 	r_strbuf_fini (&param_key);
453 	r_strbuf_fini (&param_val);
454 }
455 
save_enum(const RAnal * anal,const RAnalBaseType * type)456 static void save_enum(const RAnal *anal, const RAnalBaseType *type) {
457 	r_return_if_fail (anal && type && type->name
458 		&& type->kind == R_ANAL_BASE_TYPE_KIND_ENUM);
459 	/*
460 		C:
461 			enum name {case1 = 1, case2 = 2, caseN = 3};
462 		Sdb:
463 		name=enum
464 		enum.name=arg1,arg2,argN
465 		enum.MyEnum.0x1=arg1
466 		enum.MyEnum.0x3=arg2
467 		enum.MyEnum.0x63=argN
468 		enum.MyEnum.arg1=0x1
469 		enum.MyEnum.arg2=0x63
470 		enum.MyEnum.argN=0x3
471 	*/
472 	char *sname = r_str_sanitize_sdb_key (type->name);
473 	sdb_set (anal->sdb_types, sname, "enum", 0);
474 
475 	RStrBuf arglist;
476 	RStrBuf param_key;
477 	RStrBuf param_val;
478 	r_strbuf_init (&arglist);
479 	r_strbuf_init (&param_key);
480 	r_strbuf_init (&param_val);
481 
482 	int i = 0;
483 	RAnalEnumCase *cas;
484 	r_vector_foreach (&type->enum_data.cases, cas) {
485 		// enum.name.arg1=type,offset,???
486 		char *case_sname = r_str_sanitize_sdb_key (cas->name);
487 		sdb_set (anal->sdb_types,
488 				r_strbuf_setf (&param_key, "enum.%s.%s", sname, case_sname),
489 				r_strbuf_setf (&param_val, "0x%" PFMT32x "", cas->val), 0);
490 
491 		sdb_set (anal->sdb_types,
492 				r_strbuf_setf (&param_key, "enum.%s.0x%" PFMT32x "", sname, cas->val),
493 				case_sname, 0);
494 		free (case_sname);
495 
496 		r_strbuf_appendf (&arglist, (i++ == 0) ? "%s" : ",%s", cas->name);
497 	}
498 	// enum.name=arg1,arg2,argN
499 	char *key = r_str_newf ("enum.%s", sname);
500 	sdb_set (anal->sdb_types, key, r_strbuf_get (&arglist), 0);
501 	free (key);
502 
503 	free (sname);
504 
505 	r_strbuf_fini (&arglist);
506 	r_strbuf_fini (&param_key);
507 	r_strbuf_fini (&param_val);
508 }
509 
save_atomic_type(const RAnal * anal,const RAnalBaseType * type)510 static void save_atomic_type(const RAnal *anal, const RAnalBaseType *type) {
511 	r_return_if_fail (anal && type && type->name
512 		&& type->kind == R_ANAL_BASE_TYPE_KIND_ATOMIC);
513 	/*
514 		C: (cannot define a custom atomic type)
515 		Sdb:
516 		char=type
517 		type.char=c
518 		type.char.size=8
519 	*/
520 	char *sname = r_str_sanitize_sdb_key (type->name);
521 	sdb_set (anal->sdb_types, sname, "type", 0);
522 
523 	RStrBuf key;
524 	RStrBuf val;
525 	r_strbuf_init (&key);
526 	r_strbuf_init (&val);
527 
528 	sdb_set (anal->sdb_types,
529 			r_strbuf_setf (&key, "type.%s.size", sname),
530 			r_strbuf_setf (&val, "%" PFMT64u "", type->size), 0);
531 
532 	sdb_set (anal->sdb_types,
533 			r_strbuf_setf (&key, "type.%s", sname),
534 			type->type, 0);
535 
536 	free (sname);
537 
538 	r_strbuf_fini (&key);
539 	r_strbuf_fini (&val);
540 }
save_typedef(const RAnal * anal,const RAnalBaseType * type)541 static void save_typedef(const RAnal *anal, const RAnalBaseType *type) {
542 	r_return_if_fail (anal && type && type->name && type->kind == R_ANAL_BASE_TYPE_KIND_TYPEDEF);
543 	/*
544 		C:
545 		typedef char byte;
546 		Sdb:
547 		byte=typedef
548 		typedef.byte=char
549 	*/
550 	char *sname = r_str_sanitize_sdb_key (type->name);
551 	sdb_set (anal->sdb_types, sname, "typedef", 0);
552 
553 	RStrBuf key;
554 	RStrBuf val;
555 	r_strbuf_init (&key);
556 	r_strbuf_init (&val);
557 
558 	sdb_set (anal->sdb_types,
559 			r_strbuf_setf (&key, "typedef.%s", sname),
560 			r_strbuf_setf (&val, "%s", type->type), 0);
561 
562 	free (sname);
563 
564 	r_strbuf_fini (&key);
565 	r_strbuf_fini (&val);
566 }
567 
r_anal_base_type_free(RAnalBaseType * type)568 R_API void r_anal_base_type_free(RAnalBaseType *type) {
569 	r_return_if_fail (type);
570 	R_FREE (type->name);
571 	R_FREE (type->type);
572 
573 	switch (type->kind) {
574 	case R_ANAL_BASE_TYPE_KIND_STRUCT:
575 		r_vector_fini (&type->struct_data.members);
576 		break;
577 	case R_ANAL_BASE_TYPE_KIND_UNION:
578 		r_vector_fini (&type->union_data.members);
579 		break;
580 	case R_ANAL_BASE_TYPE_KIND_ENUM:
581 		r_vector_fini (&type->enum_data.cases);
582 		break;
583 	case R_ANAL_BASE_TYPE_KIND_TYPEDEF:
584 	case R_ANAL_BASE_TYPE_KIND_ATOMIC:
585 		break;
586 	default:
587 		break;
588 	}
589 	R_FREE (type);
590 }
591 
r_anal_base_type_new(RAnalBaseTypeKind kind)592 R_API RAnalBaseType *r_anal_base_type_new(RAnalBaseTypeKind kind) {
593 	RAnalBaseType *type = R_NEW0 (RAnalBaseType);
594 	if (!type) {
595 		return NULL;
596 	}
597 	type->kind = kind;
598 	switch (type->kind) {
599 	case R_ANAL_BASE_TYPE_KIND_STRUCT:
600 		r_vector_init (&type->struct_data.members, sizeof (RAnalStructMember), struct_type_member_free, NULL);
601 		break;
602 	case R_ANAL_BASE_TYPE_KIND_ENUM:
603 		r_vector_init (&type->enum_data.cases, sizeof (RAnalEnumCase), enum_type_case_free, NULL);
604 		break;
605 	case R_ANAL_BASE_TYPE_KIND_UNION:
606 		r_vector_init (&type->union_data.members, sizeof (RAnalUnionMember), union_type_member_free, NULL);
607 		break;
608 	default:
609 		break;
610 	}
611 
612 	return type;
613 }
614 
615 /**
616  * @brief Saves RAnalBaseType into the SDB
617  *
618  * @param anal
619  * @param type RAnalBaseType to save
620  * @param name Name of the type
621  */
r_anal_save_base_type(const RAnal * anal,const RAnalBaseType * type)622 R_API void r_anal_save_base_type(const RAnal *anal, const RAnalBaseType *type) {
623 	r_return_if_fail (anal && type && type->name);
624 
625 	// TODO, solve collisions, if there are 2 types with the same name and kind
626 
627 	switch (type->kind) {
628 	case R_ANAL_BASE_TYPE_KIND_STRUCT:
629 		save_struct (anal, type);
630 		break;
631 	case R_ANAL_BASE_TYPE_KIND_ENUM:
632 		save_enum (anal, type);
633 		break;
634 	case R_ANAL_BASE_TYPE_KIND_UNION:
635 		save_union (anal, type);
636 		break;
637 	case R_ANAL_BASE_TYPE_KIND_TYPEDEF:
638 		save_typedef (anal, type);
639 		break;
640 	case R_ANAL_BASE_TYPE_KIND_ATOMIC:
641 		save_atomic_type (anal, type);
642 		break;
643 	default:
644 		break;
645 	}
646 }
647