Exemple #1
0
SDB_API int sdb_array_add_sorted_num(Sdb *s, const char *key, ut64 val, ut32 cas) {
	int i;
	char valstr[64];
	const char *str = sdb_const_get (s, key, 0);
	const char *n = str;
	if (!str || !*str)
		return sdb_set (s, key, sdb_itoa (val, valstr, SDB_NUM_BASE), cas);
	for (i=0; n != NULL; i++) {
		if (val <= sdb_atoi(n))
			break;
		sdb_const_anext(n, &n);
	}
	if (n == NULL)
		i = -1;
	sdb_array_insert_num (s, key, i, val, cas);
	return 0;
}
Exemple #2
0
SDB_API char *sdb_array_pop_head(Sdb *s, const char *key, ut32 *cas) {
	// remove last element in 
	ut32 kas;
	char *end, *str = sdb_get (s, key, &kas);
	if (!str || !*str) {
		free (str);
		return NULL;
	}
	if (cas && *cas != kas)
		*cas = kas;
	end = strchr (str, SDB_RS);
	if (end) {
		*end = 0;
		sdb_set (s, key, end + 1, 0);
	} else {
		sdb_unset (s, key, 0);
	}
	return str;
}
Exemple #3
0
// TODO: done, but there's room for improvement
SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
	int lnstr, lstr, lval;
	const char *str = sdb_const_get_len (s, key, &lstr, 0);
	char *x, *ptr;
	if (!str || !*str)
		return sdb_set (s, key, val, cas);
	lval = strlen (val);
	lstr--;
	//lstr = strlen (str); // we can optimize this by caching value len in memory . add sdb_const_get_size()
	x = malloc (lval + lstr + 2);
	if (idx==-1) {
		memcpy (x, str, lstr);
		x[lstr] = SDB_RS;
		memcpy (x+lstr+1, val, lval+1);
	} else if (idx == 0) {
		memcpy (x, val, lval);
		x[lval] = SDB_RS;
		memcpy (x+lval+1, str, lstr+1);
	} else {
		char *nstr = malloc (lstr+1);
		memcpy (nstr, str, lstr+1);
		ptr = (char *)Aindexof (nstr, idx);
		if (ptr) {
			int lptr = (nstr+lstr+1)-ptr;
			*(ptr-1) = 0;
			lnstr = ptr-nstr-1;
			memcpy (x, nstr, lnstr);
			x[lnstr] = SDB_RS;
			memcpy (x+lnstr+1, val, lval);
			x[lnstr+lval+1] = SDB_RS;
			// TODO: this strlen hurts performance
			memcpy (x+lval+2+lnstr, ptr, lptr); //strlen (ptr)+1);
			free (nstr);
		} else {
			// this is not efficient
			free (nstr);
			free (x);
			// fallback for empty buckets
			return sdb_array_set (s, key, idx, val, cas);
		}
	}
	return sdb_set_owned (s, key, x, cas);
}
Exemple #4
0
// TODO: Add APIs to resize meta? nope, just del and add
R_API int r_meta_set_string(RAnal *a, int type, ut64 addr, const char *s) {
	char key[100], val[2048], *e_str;
	int ret;
	ut64 size;
	snprintf (key, sizeof (key)-1, "meta.%c", type);
	sdb_array_add_num (DB, key, addr, 0);
	snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, addr);
	size = sdb_array_get_num (DB, key, 0, 0);
	if (!size) {
		size = strlen (s);
		meta_inrange_add (a, addr, size);
		ret = R_TRUE;
	} else ret = R_FALSE;
	e_str = sdb_encode ((const void*)s, -1);
	snprintf (val, sizeof (val)-1, "%d,%s", (int)size, e_str);
	sdb_set (DB, key, val, 0);
	free ((void*)e_str);
	return ret;
}
Exemple #5
0
SDB_API int sdb_array_set(Sdb *s, const char *key, int idx, const char *val, ut32 cas) {
	char *ptr;
	int lstr, lval, len;
	const char *usr, *str = sdb_const_get_len (s, key, &lstr, 0);
	if (!str || !*str)
		return sdb_set (s, key, val, cas);
	// XXX: should we cache sdb_alen value inside kv?
	len = sdb_alen (str);
	lstr--;
	if (idx<0 || idx==len) // append
		return sdb_array_insert (s, key, -1, val, cas);
	lval = strlen (val);
	if (idx>len) {
		int ret, i, ilen = idx-len;
		char *newkey = malloc (ilen+lval+1);
		if (!newkey)
			return 0;
		for (i=0; i<ilen; i++)
			newkey [i] = SDB_RS;
		memcpy (newkey+i, val, lval+1);
		ret = sdb_array_insert (s, key, -1, newkey, cas);
		free (newkey);
		return ret;
	}
	//lstr = strlen (str);
	ptr = (char*)Aindexof (str, idx);
	if (ptr) {
		int diff = ptr-str;
		char *nstr = malloc (lstr+lval+2);
		ptr = nstr+diff;
		//memcpy (nstr, str, lstr+1);
		memcpy (nstr, str, diff);
		memcpy (ptr, val, lval+1);
		usr = Aindexof (str, idx+1);
		if (usr) {
			ptr[lval] = SDB_RS;
			strcpy (ptr+lval+1, usr);
		}
		return sdb_set_owned (s, key, nstr, 0);
	}
	return 0;
}
Exemple #6
0
R_API int r_meta_set_var_comment (RAnal *a, int type, ut64 idx, ut64 addr, const char *s) {
	char key[100], val[2048], *e_str;
	int ret;
	ut64 size;
	int space_idx = a->meta_spaces.space_idx;
	meta_type_add (a, type, addr);

	snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x".0x%"PFMT64x, type, addr, idx);
	size = sdb_array_get_num (DB, key, 0, 0);
	if (!size) {
		size = strlen (s);
		meta_inrange_add (a, addr, size);
		ret = true;
	} else ret = false;
	e_str = sdb_encode ((const void*)s, -1);
	snprintf (val, sizeof (val)-1, "%d,%d,%s", (int)size, space_idx, e_str);
	sdb_set (DB, key, val, 0);
	free ((void*)e_str);
	return ret;
}
Exemple #7
0
static int trace_hook_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
	char *hexbuf = malloc ((1+len)*3);
	int ret = 0;
	if (esil->cb.mem_read) {
		ret = esil->cb.mem_read (esil, addr, buf, len);
	}
	sdb_array_add_num (DB, KEY ("mem.read"), addr, 0);
	r_hex_bin2str (buf, len, hexbuf);
	sdb_set (DB, KEYAT ("mem.read.data", addr), hexbuf, 0);
	eprintf ("[ESIL] MEM READ 0x%08"PFMT64x" %s\n", addr, hexbuf);
	free (hexbuf);

	if (ocbs.hook_mem_read) {
		RAnalEsilCallbacks cbs = esil->cb;
		esil->cb = ocbs;
		ret = ocbs.hook_mem_read (esil, addr, buf, len);
		esil->cb = cbs;
	}
	return ret;
}
Exemple #8
0
static int meta_add(RAnal *a, int type, int subtype, ut64 from, ut64 to, const char *str) {
	int space_idx = a->meta_spaces.space_idx;
	char *e_str, key[100], val[2048];
	int exists;
	if (from > to) {
		return false;
	}
	if (from == to) {
		to = from + 1;
	}
	if (type == 100 && (to - from) < 1) {
		return false;
	}
	/* set entry */
	e_str = sdb_encode ((const void*)str, -1);
	RAnalMetaItem mi = {from, to, (int)(to - from), type, subtype, e_str, space_idx};
	meta_serialize (&mi, key, sizeof (key), val, sizeof (val));
	exists = sdb_exists (DB, key);

	sdb_set (DB, key, val, 0);
	free (e_str);

	// XXX: This is totally inefficient, using array_add withuot
	// checking return value is wrong practice, also it may lead
	// to inconsistent DB, and pretty bad performance. We should
	// store this list in a different storage that doesnt have
	// those limits and it's O(1) instead of O(n)
	snprintf (key, sizeof (key) - 1, "meta.0x%"PFMT64x, from);
	if (exists) {
		const char *value = sdb_const_get (DB, key, 0);
		int idx = sdb_array_indexof (DB, key, value, 0);
		sdb_array_delete (DB, key, idx, 0);
	}
	snprintf (val, sizeof (val)-1, "%c", type);
	sdb_array_add (DB, key, val, 0);
	meta_inrange_add (a, from, to - from);
	return true;
}
Exemple #9
0
R_API int r_meta_add(RAnal *a, int type, ut64 from, ut64 to, const char *str) {
	int exists;
	char *e_str, key[100], val[2048];
	if (from>to)
		return R_FALSE;
	if (from == to)
		to = from+1;
	if (type == 100) {
		if ((to-from)<3) {
			return R_FALSE;
		}
	}
	/* set entry */
	e_str = sdb_encode ((const void*)str, -1);
	snprintf (key, sizeof (key)-1, "meta.%c.0x%"PFMT64x, type, from);
	snprintf (val, sizeof (val)-1, "%d,%s", (int)(to-from), e_str);
	exists = sdb_exists (DB, key);
	sdb_set (DB, key, val, 0);
	free (e_str);

	// XXX: This is totally inefficient, using array_add withuot
	// checking return value is wrong practice, also it may lead
	// to inconsistent DB, and pretty bad performance. We should
	// store this list in a different storage that doesnt have
	// those limits and it's O(1) instead of O(n)
	if (!exists) {
		/* set type index */
		snprintf (key, sizeof (key)-1, "meta.0x%"PFMT64x, from);
		snprintf (val, sizeof (val)-1, "%c", type);
		sdb_array_add (DB, key, val, 0);
		/* set type index */
		snprintf (key, sizeof (key)-1, "meta.%c", type);
		sdb_array_add_num (DB, key, from, 0);
	}

	return R_TRUE;
}
Exemple #10
0
static bool addItem(RAnal *a, RSignItem *it) {
	char key[R_SIGN_KEY_MAXSZ], val[R_SIGN_VAL_MAXSZ];
	const char *curval;
	bool retval = true;
	RSignItem *curit = R_NEW0 (RSignItem);

	serialize (a, it, key, val);
	curval = sdb_const_get (a->sdb_zigns, key, 0);
	if (curval) {
		if (!deserialize (a, curit, key, curval)) {
			eprintf ("error: cannot deserialize zign\n");
			retval = false;
			goto exit_function;
		}
		mergeItem (curit, it);
		serialize (a, curit, key, val);
	}
	sdb_set (a->sdb_zigns, key, val, 0);

exit_function:
	free (curit);

	return retval;
}
Exemple #11
0
R_API void r_cons_pal_update_event() {
	Sdb *db = sdb_new0 ();
	int i, n = 0;
	char **color;
	/* Compute cons->pal values */
	for (i = 0; keys[i].name; i++) {
		RColor *rcolor = RCOLOR_AT (i);
		color = COLOR_AT (i);
		// Color is dynamically allocated, needs to be freed
		if (*color) {
			R_FREE (*color);
		}
		*color = r_cons_rgb_str (NULL, 0, rcolor);
		const char *rgb = sdb_fmt ("rgb:%02x%02x%02x", rcolor->r, rcolor->g, rcolor->b);
		sdb_set (db, rgb, "1", 0);
	}
	SdbList *list = sdb_foreach_list (db, true);
	SdbListIter *iter;
	SdbKv *kv;
	r_cons_rainbow_free ();
	r_cons_rainbow_new (list->length);
	ls_foreach (list, iter, kv) {
		r_cons_singleton ()->pal.rainbow[n++] = strdup (kv->key);
	}
Exemple #12
0
static void cons_pal_update_event(RConsContext *ctx) {
	Sdb *db = sdb_new0 ();
	int i, n = 0;
	char **color;
	/* Compute cons->pal values */
	for (i = 0; keys[i].name; i++) {
		RColor *rcolor = (RColor *) (((ut8 *) &(ctx->cpal)) + keys[i].coff);
		color = (char **) (((ut8 *) &(ctx->pal)) + keys[i].off);
		// Color is dynamically allocated, needs to be freed
		if (*color) {
			R_FREE (*color);
		}
		*color = r_cons_rgb_str_mode (ctx->color, NULL, 0, rcolor);
		const char *rgb = sdb_fmt ("rgb:%02x%02x%02x", rcolor->r, rcolor->g, rcolor->b);
		sdb_set (db, rgb, "1", 0);
	}
	SdbList *list = sdb_foreach_list (db, true);
	SdbListIter *iter;
	SdbKv *kv;
	r_cons_rainbow_free (ctx);
	r_cons_rainbow_new (ctx, list->length);
	ls_foreach (list, iter, kv) {
		ctx->pal.rainbow[n++] = strdup (sdbkv_key (kv));
	}
Exemple #13
0
SDB_VISIBLE int sdb_setn(Sdb *s, const char *key, ut64 v, ut32 cas) {
	char b[128];
	sdb_itoa (v, b);
	return sdb_set (s, key, b, cas);
}
Exemple #14
0
static int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) {
	int relocations_size, dos_file_size;
	if (!(bin->dos_header = R_NEW0 (MZ_image_dos_header))) {
		r_sys_perror ("malloc (MZ_image_dos_header)");
		return false;
	}
	// TODO: read field by field to avoid endian and alignment issues
	if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header,
			sizeof (*bin->dos_header)) == -1) {
		eprintf ("Error: read (MZ_image_dos_header)\n");
		return false;
	}

	if (bin->dos_header->blocks_in_file < 1) {
		return false;
	}
	dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \
			bin->dos_header->bytes_in_last_block;

	bin->dos_file_size = dos_file_size;
	if (dos_file_size > bin->size) {
		return false;
	}
	relocations_size = bin->dos_header->num_relocs * sizeof (MZ_image_relocation_entry);
	if ((bin->dos_header->reloc_table_offset + relocations_size) > bin->size) {
		return false;
	}

	sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0);
	sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0);
	sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0);
	sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0);
	sdb_num_set (bin->kv, "mz.overlay_number", bin->dos_header->overlay_number, 0);
	sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0);
	sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww"
			" signature bytes_in_last_block blocks_in_file num_relocs "
			" header_paragraphs min_extra_paragraphs max_extra_paragraphs "
			" ss sp checksum ip cs reloc_table_offset overlay_number ", 0);

	bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \
		sizeof (MZ_image_dos_header);

	if (bin->dos_extended_header_size > 0) {
		if (!(bin->dos_extended_header =
			      malloc (bin->dos_extended_header_size))) {
			r_sys_perror ("malloc (dos extended header)");
			return false;
		}
		if (r_buf_read_at (bin->b, sizeof (MZ_image_dos_header),
				(ut8*)bin->dos_extended_header,
				bin->dos_extended_header_size) == -1) {
			eprintf ("Error: read (dos extended header)\n");
			return false;
		}
	}

	if (relocations_size > 0) {
		if (!(bin->relocation_entries = malloc (relocations_size))) {
			r_sys_perror ("malloc (dos relocation entries)");
			return false;
		}
		if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset,
				(ut8*)bin->relocation_entries, relocations_size) == -1) {
			eprintf ("Error: read (dos relocation entries)\n");
			R_FREE (bin->relocation_entries);
			return false;
		}
	}
	return true;
}
Exemple #15
0
R_API int r_core_pseudo_code (RCore *core, const char *input) {
	Sdb *db;
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal,
		core->offset, R_ANAL_FCN_TYPE_NULL);
	int asmpseudo = r_config_get_i (core->config, "asm.pseudo");
	int asmdecode = r_config_get_i (core->config, "asm.decode");
	int asmlines = r_config_get_i (core->config, "asm.lines");
	int asmbytes = r_config_get_i (core->config, "asm.bytes");
	int asmoffset = r_config_get_i (core->config, "asm.offset");
	int asmflags = r_config_get_i (core->config, "asm.flags");
	int asmfcnlines = r_config_get_i (core->config, "asm.fcnlines");
	int asmcomments = r_config_get_i (core->config, "asm.comments");
	int asmfunctions = r_config_get_i (core->config, "asm.functions");
	if (!fcn) {
		eprintf ("Cannot find function in 0x%08"PFMT64x"\n",
			core->offset);
		return R_FALSE;
	}
	r_config_set_i (core->config, "asm.pseudo", 1);
	r_config_set_i (core->config, "asm.decode", 0);
	r_config_set_i (core->config, "asm.lines", 0);
	r_config_set_i (core->config, "asm.bytes", 0);
	r_config_set_i (core->config, "asm.offset", 0);
	r_config_set_i (core->config, "asm.flags", 0);
	r_config_set_i (core->config, "asm.fcnlines", 0);
	r_config_set_i (core->config, "asm.comments", 0);
	r_config_set_i (core->config, "asm.functions", 0);

	db = sdb_new0 ();

	/* */
	// walk all basic blocks
	// define depth level for each block
	// use it for indentation
	// asm.pseudo=true
	// asm.decode=true
	RAnalBlock *bb = r_list_first (fcn->bbs);
	char indentstr[1024];
	int n_bb = r_list_length (fcn->bbs);
	r_cons_printf ("function %s () {", fcn->name);
	int indent = 1;
	int nindent = 1;

	do {
#define I_TAB 4
#define K_ELSE(x) sdb_fmt(0,"else.%"PFMT64x,x)
#define K_INDENT(x) sdb_fmt(0,"loc.%"PFMT64x,x)
#define SET_INDENT(x) { memset (indentstr, ' ', x*I_TAB); indentstr [(x*I_TAB)-2] = 0; }
		if (!bb) break;
		r_cons_push ();
		char *code = r_core_cmd_str (core, sdb_fmt(0,
			"pDI %d @ 0x%08"PFMT64x"\n", bb->size, bb->addr));
		r_cons_pop ();
		memset (indentstr, ' ', indent*I_TAB);
		indentstr [(indent*I_TAB)-2] = 0;
		code = r_str_prefix_all (code, indentstr);
		code[strlen(code)-1] = 0; // chop last newline
		//r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
		//if (nindent != indent) {
		//	r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
		//}
			r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
		indentstr[(indent*I_TAB)-2] = 0;
		r_cons_printf ("\n%s", code);
		free (code);
		if (sdb_get (db, K_INDENT(bb->addr), 0)) {
			// already analyzed, go pop and continue
			// XXX check if cant pop
			//eprintf ("%s// 0x%08llx already analyzed\n", indentstr, bb->addr);
			ut64 addr = sdb_array_pop_num (db, "indent", NULL);
			if (addr==UT64_MAX) {
				int i;
				nindent = 1;
				for (i=indent; i!=nindent; i--) {
					SET_INDENT (i);
					r_cons_printf ("\n%s}", indentstr);
				}
				r_cons_printf ("\n%sreturn;\n", indentstr);
				break;
			}
			if (sdb_num_get (db, K_ELSE(bb->addr), 0)) {
				r_cons_printf ("\n%s} else {", indentstr);
			} else {
				r_cons_printf ("\n%s}", indentstr);
			}
			r_cons_printf ("\n%s  goto loc_0x%llx", indentstr, addr);
			bb = r_anal_bb_from_offset (core->anal, addr);
			if (!bb) {
				eprintf ("failed block\n");
				break;
			}
			//eprintf ("next is %llx\n", addr);
			nindent = sdb_num_get (db, K_INDENT(addr), NULL);
			if (indent>nindent) {
				int i;
				for (i=indent; i!=nindent; i--) {
					SET_INDENT (i);
					r_cons_printf ("\n%s}", indentstr);
				}
			}
			indent = nindent;
		} else {
			sdb_set (db, K_INDENT(bb->addr), "passed", 0);
			if (bb->jump != UT64_MAX) {
				int swap = 1;
				// TODO: determine which branch take first
				ut64 jump = swap? bb->jump: bb->fail;
				ut64 fail = swap? bb->fail: bb->jump;
				// if its from another function chop it!
				RAnalFunction *curfcn = r_anal_get_fcn_in (core->anal, jump, R_ANAL_FCN_TYPE_NULL);
				if (curfcn != fcn) {
					// chop that branch
					r_cons_printf ("\n  // chop\n");
					break;
				}
				if (sdb_get (db, K_INDENT(jump), 0)) {
					// already tracekd
					if (!sdb_get (db, K_INDENT(fail), 0)) {
						bb = r_anal_bb_from_offset (core->anal, fail);
					}
				} else {
					bb = r_anal_bb_from_offset (core->anal, jump);
					if (!bb) {
						eprintf ("failed to retrieve blcok at 0x%"PFMT64x"\n", jump);
						break;
					}
					if (fail != UT64_MAX) {
						// do not push if already pushed
						indent++;
						if (sdb_get (db, K_INDENT(bb->fail), 0)) {
							/* do nothing here */
							eprintf ("BlockAlready 0x%"PFMT64x"\n", bb->addr);
						} else {
					//		r_cons_printf (" { RADICAL %llx\n", bb->addr);
							sdb_array_push_num (db, "indent", fail, 0);
							sdb_num_set (db, K_INDENT(fail), indent, 0);
							sdb_num_set (db, K_ELSE(fail), 1, 0);
							r_cons_printf (" {");
						}
					} else {
						r_cons_printf (" do");
						sdb_array_push_num (db, "indent", jump, 0);
						sdb_num_set (db, K_INDENT(jump), indent, 0);
						sdb_num_set (db, K_ELSE(jump), 1, 0);
						r_cons_printf (" {");
						indent++;
					}
				}
			} else {
				ut64 addr = sdb_array_pop_num (db, "indent", NULL);
				if (addr==UT64_MAX) {
					r_cons_printf ("\nbreak\n");
					break;
				}
				bb = r_anal_bb_from_offset (core->anal, addr);
				nindent = sdb_num_get (db, K_INDENT(addr), NULL);
				if (indent>nindent) {
					int i;
					for (i=indent; i!=nindent; i--) {
						SET_INDENT (i);
						r_cons_printf ("\n%s}", indentstr);
					}
				}
				if (nindent != indent) {
					r_cons_printf ("\n%s} else {\n", indentstr);
				}
				indent = nindent;
			}
		}
		//n_bb --;
	} while (n_bb>0);
	r_cons_printf ("}\n");
	r_cons_flush ();
	r_config_set_i (core->config, "asm.pseudo", asmpseudo);
	r_config_set_i (core->config, "asm.decode", asmdecode);
	r_config_set_i (core->config, "asm.lines", asmlines);
	r_config_set_i (core->config, "asm.bytes", asmbytes);
	r_config_set_i (core->config, "asm.offset", asmoffset);
	r_config_set_i (core->config, "asm.flags", asmflags);
	r_config_set_i (core->config, "asm.fcnlines", asmfcnlines);
	r_config_set_i (core->config, "asm.comments", asmcomments);
	r_config_set_i (core->config, "asm.functions", asmfunctions);
	sdb_free (db);
	return R_TRUE;
}
Exemple #16
0
SDB_VISIBLE char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd) {
	const char *q;
	char *p, *eq, *ask;
	int i, ok, w, alength;
	ut64 n;
	if (!s) return NULL;
	if (cmd == NULL) {
		cmd = buf;
		buf = NULL;
	}
	if (!len || !buf) buf = malloc ((len=32));

	ask = strchr (cmd, '?');
	if (*cmd == '+' || *cmd == '-') {
		*buf = 0;
		if (ask) {
			*ask = 0;
			if (*cmd=='+') n = sdb_json_inc (s, cmd+1, ask+1, 1, 0);
			else n = sdb_json_dec (s, cmd+1, ask+1, 1, 0);
			*ask = '?';
		} else {
			if (*cmd=='+') n = sdb_inc (s, cmd+1, 1, 0);
			else n = sdb_dec (s, cmd+1, 1, 0);
		}
		w = snprintf (buf, len-1, "%"ULLFMT"d", n);
		if (w<0 || (size_t)w>len) {
			buf = malloc (0xff);
			snprintf (buf, 0xff, "%"ULLFMT"d", n);
		}
		return buf;
	} else if (*cmd == '(') {
		p = strchr (cmd, ')');
		if (!p) {
			fprintf (stderr, "Missing ')'.\n");
			return NULL;
		}
		*p = 0;
		eq = strchr (p+1, '=');
		if (cmd[1]=='?') {
			// if (!eq) { ...
			alength = sdb_alength (s, p+1);
			w = snprintf (buf, len, "%d", alength);
			if (w<0 || (size_t)w>len) {
				buf = malloc (32);
				snprintf (buf, 32, "%d", alength);
			}
			return buf;
		}
		if (cmd[1]) {
			/* (+)foo=bla (-)foo=bla */
			if ((cmd[1]=='+'||cmd[1]=='-') && !cmd[2]) {
				if (eq) {
					*eq = 0;
					if (cmd[1]=='+') {
						if (sdb_agetv (s, p+1, eq+1, 0)== -1)
							sdb_aset (s, p+1, -1, eq+1, 0);
					} else {
						sdb_adels (s, p+1, eq+1, 0);
					}
					return NULL;
				} else {
					if (cmd[1]=='+') {
						// (+)foo :: remove first element
						sdb_adel (s, p+1, 0, 0);
					} else {
						// (-)foo :: remove last element
						sdb_adel (s, p+1, -1, 0);
					}
					return NULL;
				}
			} else {
				i = atoi (cmd+1);
				if (eq) {
					*eq = 0;
					ok = eq[1]? (
							(cmd[1]=='+')?
							sdb_ains (s, p+1, i, eq+1, 0):
							sdb_aset (s, p+1, i, eq+1, 0)
						    ): sdb_adel (s, p+1, i, 0);
					if (ok) *buf = 0; else buf = NULL;
					return buf;
				}
				return sdb_aget (s, p+1, i, NULL);
			}
		} else {
			if (eq) {
				char *q, *out = strdup (eq+1);
				*eq = 0;
				// TODO: define new printable separator character
				for (q=out; *q; q++) if (*q==',') *q = SDB_RS;
				ok = sdb_set (s, p+1, out, 0);
				free (out);
				if (ok) {
					*buf = 0;
					return buf;
				}
			} else {
				const char *out = sdb_getc (s, p+1, 0);
				size_t wl;
				if (!out) return NULL;
				wl = strlen (out);
				if (wl>len) buf = malloc (wl+2);
				for (i=0; out[i]; i++) {
					if (out[i+1])
					buf[i] = out[i]==SDB_RS? '\n': out[i];
					else buf[i] = out[i];
				}
				buf[i] = 0;
				return buf;
			}
		}
	} else {
		eq = strchr (cmd, '=');
		if (eq) {
			// 1 0 kvpath=value
			// 1 1 kvpath?jspath=value
			if (ask>eq) ask = NULL;
			*eq++ = 0;
			if (ask) {
				*ask++ = 0;
				ok = sdb_json_set (s, cmd, ask, eq, 0);
			} else ok = sdb_set (s, cmd, eq, 0);
			if (!ok) return NULL;
			*buf = 0;
			return buf;
		} else {
			// 0 1 kvpath?jspath
			// 0 0 kvpath
			if (ask) {
				*ask++ = 0;
				// TODO: not optimized to reuse 'buf'
				if ((p = sdb_json_get (s, cmd, ask, 0)))
					return p;
			} else {
				// sdbget
				if (!(q = sdb_getc (s, cmd, 0)))
					return NULL;
				if (strlen (q)> len) return strdup (q);
				strcpy (buf, q);
				return buf;
			}
		}
	}
	return NULL;
}
Exemple #17
0
// set if not defined
SDB_VISIBLE int sdb_add (Sdb *s, const char *key, const char *val, ut32 cas) {
	if (sdb_exists (s, key))
		return 0;
	return sdb_set (s, key, val, cas);
}
Exemple #18
0
static int lmf_header_load(lmf_header *lmfh, RBuffer *buf, Sdb *db) {
	if (r_buf_size (buf) < sizeof (lmf_header)) {
		return false;
	}
	if (r_buf_fread_at (buf, QNX_HEADER_ADDR, (ut8 *) lmfh, "iiiiiiiicccciiiicc", 1) < QNX_HDR_SIZE) {
		return false;
	}
	sdb_set (db, "qnx.version", sdb_fmt ("0x%xH", lmfh->version), 0);
	sdb_set (db, "qnx.cflags", sdb_fmt ("0x%xH", lmfh->cflags), 0);
	sdb_set (db, "qnx.cpu", sdb_fmt ("0x%xH", lmfh->cpu), 0);
	sdb_set (db, "qnx.fpu", sdb_fmt ("0x%xH", lmfh->fpu), 0);
	sdb_set (db, "qnx.code_index", sdb_fmt ("0x%x", lmfh->code_index), 0);
	sdb_set (db, "qnx.stack_index", sdb_fmt ("0x%x", lmfh->stack_index), 0);
	sdb_set (db, "qnx.heap_index", sdb_fmt ("0x%x", lmfh->heap_index), 0);
	sdb_set (db, "qnx.argv_index", sdb_fmt ("0x%x", lmfh->argv_index), 0);
	sdb_set (db, "qnx.code_offset", sdb_fmt ("0x%x", lmfh->code_offset), 0);
	sdb_set (db, "qnx.stack_nbytes", sdb_fmt ("0x%x", lmfh->stack_nbytes), 0);
	sdb_set (db, "qnx.heap_nbytes", sdb_fmt ("0x%x", lmfh->heap_nbytes), 0);
	sdb_set (db, "qnx.image_base", sdb_fmt ("0x%x", lmfh->image_base), 0);
	return true;
}
Exemple #19
0
static int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) {
	int relocations_size, dos_file_size;

	if (!(bin->dos_header = malloc (sizeof(MZ_image_dos_header)))) {
		r_sys_perror ("malloc (MZ_image_dos_header)");
		return R_FALSE;
	}
	if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header,
			sizeof(*bin->dos_header)) == -1) {
		eprintf ("Error: read (MZ_image_dos_header)\n");
		return R_FALSE;
	}

	if (bin->dos_header->blocks_in_file < 1)
		return R_FALSE;

	dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \
			bin->dos_header->bytes_in_last_block;

	bin->dos_file_size = dos_file_size;

	if (dos_file_size > bin->size)
		return R_FALSE;

	relocations_size = bin->dos_header->num_relocs * \
		sizeof(MZ_image_relocation_entry);

	/* Check if relocation table doesn't exceed dos binary size */
	if ((bin->dos_header->reloc_table_offset + relocations_size) > \
			dos_file_size)
		return R_FALSE;

	sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0);
	sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0);
	sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0);
	sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0);
	sdb_num_set (bin->kv, "mz.overlay_number",
		bin->dos_header->overlay_number, 0);
	sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0);
	sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww"
			" signature bytes_in_last_block blocks_in_file num_relocs "
			" header_paragraphs min_extra_paragraphs max_extra_paragraphs "
			" ss sp checksum ip cs reloc_table_offset overlay_number ", 0);

	bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \
		sizeof(MZ_image_dos_header);

	if (bin->dos_extended_header_size > 0)
	{
		if (!(bin->dos_extended_header = \
				malloc (bin->dos_extended_header_size))) {
			r_sys_perror ("malloc (dos extended header)");
			return R_FALSE;
		}
		if (r_buf_read_at (bin->b, sizeof(MZ_image_dos_header),
				(ut8*)bin->dos_extended_header,
				bin->dos_extended_header_size) == -1) {
			eprintf ("Error: read (dos extended header)\n");
			return R_FALSE;
		}
	}

	if (relocations_size > 0)
	{
		if (!(bin->relocation_entries = malloc (relocations_size))) {
			r_sys_perror ("malloc (dos relocation entries)");
			return R_FALSE;
		}
		if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset,
				(ut8*)bin->relocation_entries, relocations_size) == -1) {
			eprintf ("Error: read (dos relocation entries)\n");
			return R_FALSE;
		}
	}

	return R_TRUE;
}
Exemple #20
0
// TODO: done, but there's room for improvement
SDB_API int sdb_array_insert(Sdb *s, const char *key, int idx, const char *val,
			      ut32 cas) {
	int lnstr, lstr;
	size_t lval;
	char *x, *ptr;
	const char *str = sdb_const_get_len (s, key, &lstr, 0);
	if (!str || !*str) {
		return sdb_set (s, key, val, cas);
	}
	lval = strlen (val);
	lstr--;
	// XXX: lstr is wrongly computed in sdb_const_get_with an off-by-one
	// we can optimize this by caching value len in memory . add
	// sdb_const_get_size()
	lstr = strlen (str); 

	// When removing strlen this conversion should be checked
	size_t lstr_tmp = lstr;
	if (SZT_ADD_OVFCHK (lval, lstr_tmp) || SZT_ADD_OVFCHK (lval + lstr_tmp, 2)) {
		return false;
	}
	x = malloc (lval + lstr_tmp + 2);
	if (!x) {
		return false;
	}

	if (idx == -1) {
		memcpy (x, str, lstr);
		x[lstr] = SDB_RS;
		memcpy (x + lstr + 1, val, lval + 1);
	} else if (!idx) {
		memcpy (x, val, lval);
		x[lval] = SDB_RS;
		memcpy (x + lval + 1, str, lstr + 1);
	} else {
		char *nstr = malloc (lstr + 1);
		if (!nstr) {
			free (x);
			return false;
		}
		memcpy (nstr, str, lstr + 1);
		ptr = (char *)Aindexof (nstr, idx);
		if (ptr) {
			int lptr = (nstr + lstr + 1) - ptr;
			char *p_1 = ptr > nstr? ptr - 1: ptr;
			*p_1 = 0;
			lnstr = ptr - nstr - 1;
			memcpy (x, nstr, lnstr);
			x[lnstr] = SDB_RS;
			memcpy (x + lnstr + 1, val, lval);
			x[lnstr + lval + 1] = SDB_RS;
			// TODO: this strlen hurts performance
			memcpy (x + lval + 2 + lnstr, ptr, lptr); //strlen (ptr)+1);
			free (nstr);
		} else {
			// this is not efficient
			free (nstr);
			free (x);
			// fallback for empty buckets
			return sdb_array_set (s, key, idx, val, cas);
		}
	}
	return sdb_set_owned (s, key, x, cas);
}
Exemple #21
0
SDB_API int sdb_json_set (Sdb *s, const char *k, const char *p, const char *v, ut32 cas) {
    const char *beg[3];
    const char *end[3];
    int jslen, l, idx, len[3];
    char *b, *str = NULL;
    const char *js;
    Rangstr rs;
    ut32 c;

    if (!s || !k)
        return 0;
    js = sdb_const_get_len (s, k, &jslen, &c);
    if (!js) {
        b = malloc (strlen (p)+strlen (v)+8);
        if (b) {
            int is_str = isstring (v);
            const char *q = is_str?"\"":"";
            sprintf (b, "{\"%s\":%s%s%s}", p, q, v, q);
#if 0
            /* disabled because it memleaks */
            sdb_set_owned (s, k, b, cas);
#else
            sdb_set (s, k, b, cas);
            free (b);
#endif
            return 1;
        }
        return 0;
    }
    if (cas && c != cas) {
        return 0;
    }
    rs = json_get (js, p);
    if (!rs.p) {
        char *b = malloc (jslen+strlen(k)+strlen (v)+32);
        if (b) {
            int curlen, is_str = isstring (v);
            const char *q = is_str?"\"":"";
            const char *e = ""; // XX: or comma
            if (js[0] && js[1] != '}')
                e = ",";
            curlen = sprintf (b, "{\"%s\":%s%s%s%s",
                              p, q, v, q, e);
            strcpy (b+curlen, js+1);
            // transfer ownership
            sdb_set_owned (s, k, b, cas);
            return 1;
        }
        // invalid json?
        return 0;
    }
#define WLEN(x) (int)(size_t)(end[x]-beg[x])

    beg[0] = js;
    end[0] = rs.p + rs.f;
    len[0] = WLEN (0);

    if (*v) {
        beg[1] = v;
        end[1] = v + strlen (v);
        len[1] = WLEN (1);
    }

    beg[2] = rs.p + rs.t;
    end[2] = js + jslen;
    len[2] = WLEN (2);

    // TODO: accelerate with small buffer in stack for small jsons
    if (*v) {
        int is_str = isstring (v);
        int msz = len[0]+len[1]+len[2]+strlen (v);
        if (msz<1)
            return 0;
        str = malloc (msz);
        if (!str)
            return 0;
        idx = len[0];
        memcpy (str, beg[0], idx);
        if (is_str) {
            if (beg[2][0]!='"') {
                str[idx]='"';
                idx++;
            }
        } else {
            if (beg[2][0]=='"') {
                idx--;
            }
        }
        l = len[1];
        memcpy (str+idx, beg[1], l);
        idx += len[1];
        if (is_str) {
            // TODO: add quotes
            if (beg[2][0]!='"') {
                str[idx]='"';
                idx++;
            }
        } else {
            if (beg[2][0]=='"') {
                beg[2]++;
            }
        }
        l = len[2];
        memcpy (str+idx, beg[2], l);
        str[idx+l] = 0;
    } else {
        int kidx;
        // DELETE KEY
        rs.f -= 2;
        kidx = findkey (&rs);
        len[0] = R_MAX (1, kidx-1);
        if (kidx==1) {
            if (beg[2][0]=='"')
                beg[2]++;
            beg[2]++;
        }
        str = malloc (len[0]+len[2]+1);
        if (!str)
            return 0;
        memcpy (str, beg[0], len[0]);
        if (!*beg[2])
            beg[2]--;
        memcpy (str+len[0], beg[2], len[2]);
        str[len[0]+len[2]] = 0;
    }
    sdb_set_owned (s, k, str, cas);
    return 1;
}
Exemple #22
0
// XXX: cmd is reused
SDB_API char *sdb_querys (Sdb *s, char *buf, size_t len, const char *cmd) {
	int i, d, ok, w, alength, bufset = 0;
	const char *p, *q, *val = NULL;
	char *eq, *ask;
	ut64 n;
	if (!s) return NULL;
	if (cmd == NULL) {
		cmd = buf;
		buf = NULL;
	}
	if (!len || !buf) {
		bufset = 1;
		buf = malloc ((len=64));
	}
	ask = strchr (cmd, '?');
	if (*cmd == '[') {
		char *tp = strchr (cmd, ']');
		if (!tp) {
			fprintf (stderr, "Missing ']'.\n");
			if (bufset)
				free (buf);
			return NULL;
		}
		*tp++ = 0;
		p = (const char *)tp;
	} else p = cmd;
	eq = strchr (p, '=');
	if (eq) {
		*eq++ = 0;
		if (*eq=='$')
			val = sdb_getc (s, eq+1, 0);
	}
	if (!val) val = eq;
	if (*cmd=='$')
		cmd = sdb_getc (s, cmd+1, 0);
	// cmd = val
	// cmd is key and val is value

	if (*cmd == '.') {
		sdb_query_file (s, cmd+1);
		if (bufset)
			free (buf);
		return NULL;
	} else
	if (*cmd == '+' || *cmd == '-') {
		d = 1;
		*buf = 0;
		if (val) {
			d = sdb_atoi (val);
			if (d) {
				if (*cmd=='+')
					sdb_inc (s, cmd+1, d, 0);
				else
					sdb_dec (s, cmd+1, d, 0);
			} else {
				sdb_concat (s, cmd+1, val, 0);
			}
		} else {
			if (ask) {
				*ask = 0;
				if (*cmd=='+') n = sdb_json_inc (s, cmd+1, ask+1, d, 0);
				else n = sdb_json_dec (s, cmd+1, ask+1, d, 0);
				*ask = '?';
			} else {
				if (*cmd=='+') n = sdb_inc (s, cmd+1, d, 0);
				else n = sdb_dec (s, cmd+1, d, 0);
			}
			w = snprintf (buf, len-1, "%"ULLFMT"d", n);
			if (w<0 || (size_t)w>len) {
				buf = malloc (0xff);
				snprintf (buf, 0xff, "%"ULLFMT"d", n);
			}
		}
		return buf;
	} else if (*cmd == '[') {
		// [?] - count elements of array
		if (cmd[1]=='?') {
			// if (!eq) { ...
			alength = sdb_alength (s, p);
			w = snprintf (buf, len, "%d", alength);
			if (w<0 || (size_t)w>len) {
				buf = malloc (32);
				snprintf (buf, 31, "%d", alength);
			}
			return buf;
		}
		if (cmd[1]=='+'||cmd[1]=='-') {
			// [+]foo        remove first element */
			// [+]foo=bar    PUSH */
			// [-]foo        POP */
			// [-]foo=xx     POP  (=xx ignored) */
			if (!cmd[2] || cmd[2] ==']') {
				// insert
				if (eq) {
					if (cmd[1]=='+') {
						if (sdb_agetv (s, p, val, 0)== -1)
							sdb_aset (s, p, -1, val, 0);
					} else {
						sdb_adels (s, p, val, 0);
					}
					return NULL;
				} else {
					char *ret;
					if (cmd[1]=='+') {
// XXX: this is a little strange syntax to remove an item
						ret = sdb_aget (s, p, 0, 0);
						// (+)foo :: remove first element
						sdb_adel (s, p, 0, 0);
					} else { // POP
						ret = sdb_aget (s, p, -1, 0);
						// (-)foo :: remove last element
						sdb_adel (s, p, -1, 0);
					}
					return ret;
				}
			} else {
				// get/set specific element in array
				/* (+3)foo=bla */
				i = atoi (cmd+1);
				if (eq) {
					ok = cmd[1]? (
							(cmd[1]=='+')?
							sdb_ains (s, p, i, val, 0):
							sdb_aset (s, p, i, val, 0)
						    ): sdb_adel (s, p, i, 0);
					if (ok) *buf = 0; else buf = NULL;
					return buf;
				}
				return sdb_aget (s, p, i, NULL);
			}
		} else {
			if (eq) {
				/* (3)foo=bla */
				char *q, *out = strdup (val);
				// TODO: define new printable separator character
				for (q=out; *q; q++) if (*q==',') *q = SDB_RS;
				if (cmd[1]) {
					int idx = atoi (cmd+1);
					ok = sdb_aset (s, p, idx, val, 0);
// TODO: handle when idx > sdb_alen
				} else {
					ok = sdb_set (s, p, out, 0);
				}
				free (out);
				if (ok) {
					*buf = 0;
					return buf;
				}
				return NULL;
			} else {
				/* (3)foo */
				const char *out = sdb_getc (s, p, 0);
				size_t wl;
				if (cmd[1]) {
					i = atoi (cmd+1);
					return sdb_aget (s, p, i, NULL);
				}
				if (!out) return NULL;
				wl = strlen (out);
				if (wl>len) buf = malloc (wl+2);
				for (i=0; out[i]; i++) {
					if (out[i+1])
					buf[i] = out[i]==SDB_RS? '\n': out[i];
					else buf[i] = out[i];
				}
				buf[i] = 0;
				return buf;
			}
		}
	} else {
		if (eq) {
			// 1 0 kvpath=value
			// 1 1 kvpath?jspath=value
			if (ask>eq) ask = NULL;
			if (ask) {
				*ask++ = 0;
				ok = sdb_json_set (s, cmd, ask, val, 0);
			} else ok = sdb_set (s, cmd, val, 0);
			if (!ok) {
				if (bufset)
					free (buf);
				return NULL;
			}
			*buf = 0;
			return buf;
		} else {
			// 0 1 kvpath?jspath
			// 0 0 kvpath
			if (ask) {
				*ask++ = 0;
				// TODO: not optimized to reuse 'buf'
				if ((p = sdb_json_get (s, cmd, ask, 0)))
					return strdup (p);
			} else {
				// sdbget
				if (!(q = sdb_getc (s, cmd, 0)))
					return NULL;
				if (strlen (q)> len) return strdup (q);
				strcpy (buf, q);
				return buf;
			}
		}
	}
	if (bufset)
		free (buf);
	return NULL;
}
Exemple #23
0
R_API int r_core_pseudo_code(RCore *core, const char *input) {
	Sdb *db;
	ut64 queuegoto = 0LL;
	const char *blocktype = "else";
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL);
	RConfigHold *hc = r_config_hold_new (core->config);
	if (!hc) {
		return false;
	}
	r_config_save_num (hc, "asm.pseudo", "asm.decode", "asm.lines", "asm.bytes", NULL);
	r_config_save_num (hc, "asm.offset", "asm.flags", "asm.fcnlines", "asm.comments", NULL);
	r_config_save_num (hc, "asm.functions", "asm.section", "asm.cmtcol", "asm.filter", NULL);
	r_config_save_num (hc, "scr.color", "asm.emustr", "asm.emu", "asm.emuwrite", NULL);
	if (!fcn) {
		eprintf ("Cannot find function in 0x%08"PFMT64x"\n", core->offset);
		r_config_hold_free (hc);
		return false;
	}
	r_config_set_i (core->config, "scr.color", 0);
	r_config_set_i (core->config, "asm.pseudo", 1);
	r_config_set_i (core->config, "asm.decode", 0);
	r_config_set_i (core->config, "asm.filter", 1);
	r_config_set_i (core->config, "asm.lines", 0);
	r_config_set_i (core->config, "asm.bytes", 0);
	r_config_set_i (core->config, "asm.offset", 0);
	r_config_set_i (core->config, "asm.flags", 0);
	r_config_set_i (core->config, "asm.emu", 1);
	r_config_set_i (core->config, "asm.emustr", 1);
	r_config_set_i (core->config, "asm.emuwrite", 1);
	r_config_set_i (core->config, "asm.fcnlines", 0);
	r_config_set_i (core->config, "asm.comments", 1);
	r_config_set_i (core->config, "asm.functions", 0);
	r_config_set_i (core->config, "asm.tabs", 0);
	r_config_set_i (core->config, "asm.section", 0);
	r_config_set_i (core->config, "asm.cmtcol", 30);
	r_core_cmd0 (core, "aeim");

	db = sdb_new0 ();

	/* */
	// walk all basic blocks
	// define depth level for each block
	// use it for indentation
	// asm.pseudo=true
	// asm.decode=true
	RAnalBlock *bb = r_list_first (fcn->bbs);
	char indentstr[1024];
	int n_bb = r_list_length (fcn->bbs);
	r_cons_printf ("function %s () {", fcn->name);
	int indent = 1;
	int nindent = 1;

	do {
#define I_TAB 4
#define K_MARK(x) sdb_fmt(0,"mark.%"PFMT64x,x)
#define K_ELSE(x) sdb_fmt(0,"else.%"PFMT64x,x)
#define K_INDENT(x) sdb_fmt(0,"loc.%"PFMT64x,x)
#define SET_INDENT(x) { memset (indentstr, ' ', x*I_TAB); indentstr [(x*I_TAB)-2] = 0; }
		if (!bb) break;
		r_cons_push ();
		char *code = r_core_cmd_str (core, sdb_fmt (0, "pD %d @ 0x%08"PFMT64x"\n", bb->size, bb->addr));
		r_cons_pop ();
		memset (indentstr, ' ', indent * I_TAB);
		indentstr [(indent * I_TAB) - 2] = 0;
		code = r_str_prefix_all (code, indentstr);
		int len = strlen (code);
		code[len - 1] = 0; // chop last newline
		//r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
		//if (nindent != indent) {
		//	r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
		//}
		find_and_change (code, len);
		if (!sdb_const_get (db, K_MARK (bb->addr), 0)) {
			bool mustprint = !queuegoto || queuegoto != bb->addr;
			if (mustprint) {
				if (queuegoto) {
					r_cons_printf ("\n%s  goto loc_0x%llx", indentstr, queuegoto);
					queuegoto = 0LL;
				}
				r_cons_printf ("\n%s  loc_0x%llx:\n", indentstr, bb->addr);
				indentstr[(indent * I_TAB) - 2] = 0;
				r_cons_printf ("\n%s", code);
				free (code);
				sdb_num_set (db, K_MARK (bb->addr), 1, 0);
			}
		}
		if (sdb_const_get (db, K_INDENT (bb->addr), 0)) {
			// already analyzed, go pop and continue
			// XXX check if cant pop
			//eprintf ("%s// 0x%08llx already analyzed\n", indentstr, bb->addr);
			ut64 addr = sdb_array_pop_num (db, "indent", NULL);
			if (addr == UT64_MAX) {
				int i;
				nindent = 1;
				for (i = indent; i != nindent; i--) {
					SET_INDENT (i);
					r_cons_printf ("\n%s}", indentstr);
				}
				r_cons_printf ("\n%sreturn;\n", indentstr);
				break;
			}
			if (sdb_num_get (db, K_ELSE (bb->addr), 0)) {
				if (!strcmp (blocktype, "else")) {
					r_cons_printf ("\n%s } %s {", indentstr, blocktype);
				} else {
					r_cons_printf ("\n%s } %s (?);", indentstr, blocktype);
				}
			} else {
				r_cons_printf ("\n%s}", indentstr);
			}
			if (addr != bb->addr) {
				queuegoto = addr;
				//r_cons_printf ("\n%s  goto loc_0x%llx", indentstr, addr);
			}
			bb = r_anal_bb_from_offset (core->anal, addr);
			if (!bb) {
				eprintf ("failed block\n");
				break;
			}
			//eprintf ("next is %llx\n", addr);
			nindent = sdb_num_get (db, K_INDENT (addr), NULL);
			if (indent > nindent && !strcmp (blocktype, "else")) {
				int i;
				for (i = indent; i != nindent; i--) {
					SET_INDENT (i);
					r_cons_printf ("\n%s }", indentstr);
				}
			}
			indent = nindent;
		} else {
			sdb_set (db, K_INDENT (bb->addr), "passed", 0);
			if (bb->jump != UT64_MAX) {
				int swap = 1;
				// TODO: determine which branch take first
				ut64 jump = swap ? bb->jump : bb->fail;
				ut64 fail = swap ? bb->fail : bb->jump;
				// if its from another function chop it!
				RAnalFunction *curfcn = r_anal_get_fcn_in (core->anal, jump, R_ANAL_FCN_TYPE_NULL);
				if (curfcn != fcn) {
					// chop that branch
					r_cons_printf ("\n  // chop\n");
					break;
				}
				if (sdb_get (db, K_INDENT (jump), 0)) {
					// already tracekd
					if (!sdb_get (db, K_INDENT (fail), 0)) {
						bb = r_anal_bb_from_offset (core->anal, fail);
					}
				} else {
					bb = r_anal_bb_from_offset (core->anal, jump);
					if (!bb) {
						eprintf ("failed to retrieve blcok at 0x%"PFMT64x"\n", jump);
						break;
					}
					if (fail != UT64_MAX) {
						// do not push if already pushed
						indent++;
						if (sdb_get (db, K_INDENT (bb->fail), 0)) {
							/* do nothing here */
							eprintf ("BlockAlready 0x%"PFMT64x"\n", bb->addr);
						} else {
							//		r_cons_printf (" { RADICAL %llx\n", bb->addr);
							sdb_array_push_num (db, "indent", fail, 0);
							sdb_num_set (db, K_INDENT (fail), indent, 0);
							sdb_num_set (db, K_ELSE (fail), 1, 0);
							SET_INDENT (indent);
							r_cons_printf ("\n%s {", indentstr);
						}
					} else {
						r_cons_printf ("\n%s do", indentstr);
						sdb_array_push_num (db, "indent", jump, 0);
						sdb_num_set (db, K_INDENT (jump), indent, 0);
						sdb_num_set (db, K_ELSE (jump), 1, 0);
						if (jump <= bb->addr) {
							blocktype = "while";
						} else {
							blocktype = "else";
						}
						r_cons_printf ("\n%s {", indentstr);
						indent++;
					}
				}
			} else {
				ut64 addr = sdb_array_pop_num (db, "indent", NULL);
				if (addr == UT64_MAX) {
					//r_cons_printf ("\nbreak\n");
					break;
				}
				bb = r_anal_bb_from_offset (core->anal, addr);
				nindent = sdb_num_get (db, K_INDENT (addr), NULL);
				if (indent > nindent) {
					int i;
					for (i = indent; i != nindent; i--) {
						SET_INDENT (i);
						r_cons_printf ("\n%s}", indentstr);
					}
				}
				if (nindent != indent) {
					r_cons_printf ("\n%s} else {\n", indentstr);
				}
				indent = nindent;
			}
		}
		//n_bb --;
	} while (n_bb > 0);
	r_cons_printf ("\n}\n");
	r_config_restore (hc);
	r_config_hold_free (hc);
	sdb_free (db);
	return true;
}
Exemple #24
0
R_API void r_anal_pin (RAnal *a, ut64 addr, const char *name) {
	char buf[64];
	const char *key = sdb_itoa (addr, buf, 16);
	sdb_set (DB, key, name, 0);
}
Exemple #25
0
static int art_header_load(ARTHeader *art, RBuffer *buf, Sdb *db) {
	/* TODO: handle read errors here */
	if (r_buf_size (buf) < sizeof (ARTHeader)) {
		return false;
	}
	(void) r_buf_fread_at (buf, 0, (ut8 *) art, "IIiiiiiiiiiiii", 1);
	sdb_set (db, "img.base", sdb_fmt (0, "0x%x", art->image_base), 0);
	sdb_set (db, "img.size", sdb_fmt (0, "0x%x", art->image_size), 0);
	sdb_set (db, "art.checksum", sdb_fmt (0, "0x%x", art->checksum), 0);
	sdb_set (db, "art.version", sdb_fmt (0, "%c%c%c",
			art->version[0], art->version[1], art->version[2]), 0);
	sdb_set (db, "oat.begin", sdb_fmt (0, "0x%x", art->oat_file_begin), 0);
	sdb_set (db, "oat.end", sdb_fmt (0, "0x%x", art->oat_file_end), 0);
	sdb_set (db, "oat_data.begin", sdb_fmt (0, "0x%x", art->oat_data_begin), 0);
	sdb_set (db, "oat_data.end", sdb_fmt (0, "0x%x", art->oat_data_end), 0);
	sdb_set (db, "patch_delta", sdb_fmt (0, "0x%x", art->patch_delta), 0);
	sdb_set (db, "image_roots", sdb_fmt (0, "0x%x", art->image_roots), 0);
	sdb_set (db, "compile_pic", sdb_fmt (0, "0x%x", art->compile_pic), 0);
	return true;
}
Exemple #26
0
SDB_VISIBLE int sdb_remove (Sdb* s, const char *key, ut32 cas) {
	return key? sdb_set (s, key, "", cas): 0;
}