Beispiel #1
0
static int rabin_extract(int all) {
	int res = R_FALSE;
	RBinFile *bf = r_bin_cur (bin);
	RBinObject *obj = NULL;
	if (!bf) return res;
	if (all) {
		int idx = 0;
		RListIter *iter = NULL;
		r_list_foreach (bf->objs, iter, obj)
			res = extract_binobj (bf, obj, idx++);
	} else {
		obj = r_bin_cur_object (bin);
		if (!obj) return res;
		res = extract_binobj (bf, obj, 0);
	}

	return res;
}
Beispiel #2
0
R_API void r_core_seek_archbits(RCore *core, ut64 addr) {
	int bits = 0;
	const char *arch = NULL;
	RBinObject *o = r_bin_cur_object (core->bin);
	RBinSection *s = o? r_bin_get_section_at (o, addr, core->io->va): NULL;
	if (s) {
		arch = s->arch;
		bits = s->bits;
	}
	if (!bits && !core->fixedbits) {
		//if we found bits related with anal hints pick it up
		__choose_bits_anal_hints (core, addr, &bits);
	}
	if (bits && !core->fixedbits) {
		r_config_set_i (core->config, "asm.bits", bits);
	}
	if (arch && !core->fixedarch) {
		r_config_set (core->config, "asm.arch", arch);
	}
}
Beispiel #3
0
int main(int argc, char **argv) {
	const char *query = NULL;
	int c, bits = 0, actions_done = 0, actions = 0, action = ACTION_UNK;
	char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins");
	char *ptr, *arch = NULL, *arch_name = NULL;
	const char *op = NULL;
	RCoreBinFilter filter;
	RCore core;
	RCoreFile *cf = NULL;
	int xtr_idx = 0; // load all files if extraction is necessary.
	int fd = -1;
	int rawstr = 0;

	r_core_init (&core);
	bin = core.bin;
	l = r_lib_new ("radare_plugin");
	r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins",
			   &__lib_bin_cb, &__lib_bin_dt, NULL);
	r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins",
			   &__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL);

	/* load plugins everywhere */
	r_lib_opendir (l, getenv ("LIBR_PLUGINS"));
	r_lib_opendir (l, homeplugindir);
	r_lib_opendir (l, LIBDIR"/radare2/"R2_VERSION);

#define is_active(x) (action&x)
#define set_action(x) actions++; action |=x
	while ((c = getopt (argc, argv, "jgqAf:a:B:b:c:Ck:dMm:n:N:@:isSIHelRwO:o:rvLhxzZ")) != -1) {
		switch (c) {
		case 'g':
			set_action (ACTION_CLASSES);
			set_action (ACTION_IMPORTS);
			set_action (ACTION_SYMBOLS);
			set_action (ACTION_SECTIONS);
			set_action (ACTION_STRINGS);
			set_action (ACTION_SIZE);
			set_action (ACTION_INFO);
			set_action (ACTION_FIELDS);
			set_action (ACTION_DWARF);
			set_action (ACTION_ENTRIES);
			set_action (ACTION_MAIN);
			set_action (ACTION_LIBS);
			set_action (ACTION_RELOCS);
			set_action (ACTION_EXTRACT);
			break;
		case 'q': rad = R_CORE_BIN_SIMPLE; break;
		case 'j': rad = R_CORE_BIN_JSON; break;
		case 'A': set_action (ACTION_LISTARCHS); break;
		case 'a': if (optarg) arch = optarg; break;
		case 'c':
			if (!optarg) {
				eprintf ("Missing argument for -c");
				return 1;
			}
			set_action (ACTION_CREATE);
			create = strdup (optarg);
			break;
		case 'k': query = optarg; break;
		case 'C': set_action (ACTION_CLASSES); break;
		case 'f': if (optarg) arch_name = strdup (optarg); break;
		case 'b': bits = r_num_math (NULL, optarg); break;
		case 'm':
			at = r_num_math (NULL, optarg);
			set_action (ACTION_SRCLINE);
			break;
		case 'i': set_action (ACTION_IMPORTS); break;
		case 's': set_action (ACTION_SYMBOLS); break;
		case 'S': set_action (ACTION_SECTIONS); break;
		case 'z':
			if (is_active (ACTION_STRINGS)) {
				rawstr = R_TRUE;
			} else set_action (ACTION_STRINGS);
			break;
		case 'Z': set_action (ACTION_SIZE); break;
		case 'I': set_action (ACTION_INFO); break;
		case 'H': set_action (ACTION_FIELDS); break;
		case 'd': set_action (ACTION_DWARF); break;
		case 'e': set_action (ACTION_ENTRIES); break;
		case 'M': set_action (ACTION_MAIN); break;
		case 'l': set_action (ACTION_LIBS); break;
		case 'R': set_action (ACTION_RELOCS); break;
		case 'x': set_action (ACTION_EXTRACT); break;
		case 'w': rw = R_TRUE; break;
		case 'O':
			op = optarg;
			set_action (ACTION_OPERATION);
			if (op && !strcmp (op, "help")) {
				printf ("Operation string:\n"
						"  Dump symbols: d/s/1024\n"
						"  Dump section: d/S/.text\n"
						"  Resize section: r/.data/1024\n");
				return 0;
			}
			if (optind==argc) {
				eprintf ("Missing filename\n");
				return 1;
			}
			break;
		case 'o': output = optarg; break;
		case 'r': rad = R_TRUE; break;
		case 'v': va = R_TRUE; break;
		case 'L': r_bin_list (bin); return 1;
		case 'B': baddr = r_num_math (NULL, optarg); break;
		case '@': at = r_num_math (NULL, optarg); break;
		case 'n': name = optarg; break;
		case 'N': bin->minstrlen = r_num_math (NULL, optarg); break;
		//case 'V': return blob_version ("rabin2");
		case 'h': return rabin_show_help (1);
		default: action |= ACTION_HELP;
		}
	}

	file = argv[optind];
	if (!query)
	if (action & ACTION_HELP || action == ACTION_UNK || file == NULL) {
		if (va) return blob_version ("rabin2");
		return rabin_show_help (0);
	}

	if (arch) {
		ptr = strchr (arch, '_');
		if (ptr) {
			*ptr = '\0';
			bits = r_num_math (NULL, ptr+1);
		}
	}
	if (action & ACTION_CREATE) {
		// TODO: move in a function outside
		RBuffer *b;
		int datalen, codelen;
		ut8 *data = NULL, *code = NULL;
		char *p2, *p = strchr (create, ':');
		if (!p) {
			eprintf ("Invalid format for -c flag. Use 'format:codehexpair:datahexpair'\n");
			return 1;
		}
		*p++ = 0;
		p2 = strchr (p, ':');
		if (p2) {
			// has data
			*p2++ = 0;
			data = malloc (strlen (p2)+1);
			datalen = r_hex_str2bin (p2, data);
		} else {
			data = NULL;
			datalen = 0;
		}
		code = malloc (strlen (p)+1);
		if (!code) {
		    return 1;
	    }
		codelen = r_hex_str2bin (p, code);
		if (!arch) arch = "x86";
		if (!bits) bits = 32;

		if (!r_bin_use_arch (bin, arch, bits, create)) {
			eprintf ("Cannot set arch\n");
			return 1;
		}
		b = r_bin_create (bin, code, codelen, data, datalen);
		if (b) {
			if (r_file_dump (file, b->buf, b->length)) {
				eprintf ("dumped %d bytes in '%s'\n", b->length, file);
				r_file_chmod (file, "+x", 0);
			} else eprintf ("error dumping into a.out\n");
			r_buf_free (b);
		} else eprintf ("Cannot create binary for this format '%s'.\n", create);
		r_bin_free (bin);
		return 0;
	}
	r_config_set_i (core.config, "bin.rawstr", rawstr);
	cf = r_core_file_open (&core, file, R_IO_READ, 0);
	fd = cf ? r_core_file_cur_fd (&core) : -1;
	if (!cf || fd == -1) {
		eprintf ("r_core: Cannot open file\n");
		return 1;
	}

	if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) {
		if (!r_bin_load (bin, file, baddr, 0, xtr_idx, fd, rawstr)) {
			eprintf ("r_bin: Cannot open file\n");
			return 1;
		}
	}

	if (query) {
		if (!strcmp (query, "-")) {
			__sdb_prompt (bin->cur->sdb);
		} else sdb_query (bin->cur->sdb, query);
		return 0;
	}

	// XXX: TODO move this to libr/core/bin.c
	if (action & ACTION_LISTARCHS || ((arch || bits || arch_name) &&
		!r_bin_select (bin, arch, bits, arch_name))) {
		if (rad == R_CORE_BIN_JSON) {
			int i;
			printf ("[");
			for (i = 0; i < bin->narch; i++) {
				if (r_bin_select_idx (bin, bin->file, i)) {
					RBinObject *o = r_bin_cur_object (bin);
					RBinInfo *info = o ? o->info : NULL;
					printf ("%s{\"arch\":\"%s\",\"bits\":%d,"
						"\"offset\":%"PFMT64d",\"machine\":\"%s\"}",
						i?",":"",info->arch, info->bits,
						bin->cur->offset, info->machine);
				}
			}
			printf ("]");
		} else r_bin_list_archs (bin, 1);
		free (arch_name);
	}

	if (baddr != 0LL) {
		r_bin_set_baddr (bin, baddr);
		bin->cur->o->baddr = baddr;
	}

	core.bin = bin;
	filter.offset = at;
	filter.name = name;

	r_cons_new ()->is_interactive = R_FALSE;

#define isradjson (rad==R_CORE_BIN_JSON&&actions>0)
#define run_action(n,x,y) {\
	if (action&x) {\
		if (isradjson) r_cons_printf ("\"%s\":",n);\
		if (!r_core_bin_info (&core, y, rad, va, &filter, 0)) {\
			if (isradjson) r_cons_printf("false");\
		};\
		actions_done++;\
		if (isradjson) r_cons_printf (actions==actions_done? "":",");\
	}\
}
	if (isradjson) r_cons_printf ("{");
	run_action ("sections", ACTION_SECTIONS, R_CORE_BIN_ACC_SECTIONS);
	run_action ("entries", ACTION_ENTRIES, R_CORE_BIN_ACC_ENTRIES);
	run_action ("main", ACTION_MAIN, R_CORE_BIN_ACC_MAIN);
	run_action ("imports", ACTION_IMPORTS, R_CORE_BIN_ACC_IMPORTS);
	run_action ("classes", ACTION_CLASSES, R_CORE_BIN_ACC_CLASSES);
	run_action ("symbols", ACTION_SYMBOLS, R_CORE_BIN_ACC_SYMBOLS);
	run_action ("strings", ACTION_STRINGS, R_CORE_BIN_ACC_STRINGS);
	run_action ("info", ACTION_INFO, R_CORE_BIN_ACC_INFO);
	run_action ("fields", ACTION_FIELDS, R_CORE_BIN_ACC_FIELDS);
	run_action ("libs", ACTION_LIBS, R_CORE_BIN_ACC_LIBS);
	run_action ("relocs", ACTION_RELOCS, R_CORE_BIN_ACC_RELOCS);
	run_action ("dwarf", ACTION_DWARF, R_CORE_BIN_ACC_DWARF);
	run_action ("size", ACTION_SIZE, R_CORE_BIN_ACC_SIZE);
	if (action&ACTION_SRCLINE)
		rabin_show_srcline (at);
	if (action&ACTION_EXTRACT)
		rabin_extract ((arch==NULL && arch_name==NULL && bits==0));
	if (op != NULL && action&ACTION_OPERATION)
		rabin_do_operation (op);
	if (isradjson)
		printf ("}");
	r_cons_flush ();
	r_core_fini (&core);

	return 0;
}
Beispiel #4
0
static int bin_strings(RCore *r, int mode, int va) {
	char *q, str[R_FLAG_NAME_SIZE];
	RBinSection *section;
	int hasstr, minstr, maxstr, rawstr;
	RBinString *string;
	RListIter *iter;
	RList *list;
	RBin *bin = r->bin;
	RBinFile * binfile = r_core_bin_cur (r);
	RBinPlugin *plugin = r_bin_file_cur_plugin (binfile);

	if (!binfile) return false;
	minstr = r_config_get_i (r->config, "bin.minstr");
	maxstr = r_config_get_i (r->config, "bin.maxstr");
	rawstr = r_config_get_i (r->config, "bin.rawstr");
	binfile->rawstr = rawstr;

	if (!(hasstr = r_config_get_i (r->config, "bin.strings"))) {
		return 0;
	}

	if (!plugin) return 0;
	if (plugin->info && plugin->name) {
		if (strcmp (plugin->name, "any") == 0 && !rawstr) {
			return false;
		}
	}

	bin->minstrlen = minstr;
	minstr = bin->minstrlen;

	if ((list = r_bin_get_strings (bin)) == NULL) return false;

	if (IS_MODE_JSON (mode)) r_cons_printf ("[");
	if (IS_MODE_RAD (mode)) r_cons_printf ("fs strings");
	if (IS_MODE_SET (mode) && r_config_get_i (r->config, "bin.strings")) {
		r_flag_space_set (r->flags, "strings");
		r_cons_break (NULL, NULL);
	}
	r_list_foreach (list, iter, string) {
		const char *section_name, *type_string;
		ut64 paddr = string->paddr;
		ut64 vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr);
		ut64 addr = va ? vaddr : paddr;

		if (string->length < minstr) continue;
		if (maxstr && string->length > maxstr) continue;

		section = r_bin_get_section_at (r_bin_cur_object (bin), paddr, 0);
		section_name = section ? section->name : "unknown";
		type_string = string->type == 'w' ? "wide" : "ascii";
		if (IS_MODE_SET (mode)) {
			char *f_name;

			if (r_cons_singleton()->breaked) break;
			r_meta_add (r->anal, R_META_TYPE_STRING, addr,
				addr + string->size, string->string);
			f_name = strdup (string->string);
			r_name_filter (f_name, R_FLAG_NAME_SIZE);
			snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name);
			r_flag_set (r->flags, str, addr, string->size, 0);
			free (f_name);
		} else if (IS_MODE_SIMPLE (mode)) {
			r_cons_printf ("0x%"PFMT64x" %d %d %s\n", addr,
				string->size, string->length, string->string);
		} else if (IS_MODE_JSON (mode)) {
			q = r_base64_encode_dyn (string->string, -1);
			r_cons_printf ("%s{\"vaddr\":%"PFMT64d
				",\"paddr\":%"PFMT64d",\"ordinal\":%d"
				",\"size\":%d,\"length\":%d,\"section\":\"%s\","
				"\"type\":\"%s\",\"string\":\"%s\"}",
				iter->p ? ",": "",
				vaddr, paddr, string->ordinal, string->size,
				string->length, section_name, type_string, q);
			free (q);
		} else if (IS_MODE_RAD (mode)) {
			char *f_name;

			f_name = strdup (string->string);
			r_name_filter (f_name, R_FLAG_NAME_SIZE);
			snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name);
			r_cons_printf ("f str.%s %"PFMT64d" @ 0x%08"PFMT64x"\n"
				"Cs %"PFMT64d" @ 0x%08"PFMT64x"\n",
				f_name, string->size, addr,
				string->size, addr);
			free (f_name);
		} else {
			r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08"
				PFMT64x" ordinal=%03u sz=%u len=%u "
				"section=%s type=%s string=%s\n",
				vaddr, paddr, string->ordinal, string->size,
				string->length, section_name, type_string,
				string->string);
		}
	}
	if (IS_MODE_JSON (mode)) r_cons_printf ("]");
	if (IS_MODE_SET (mode)) r_cons_break_end ();

	return true;
}
static int cmd_info(void *data, const char *input) {
	RCore *core = (RCore *)data;
	int newline = r_config_get_i (core->config, "scr.interactive");
	ut64 offset = r_bin_get_offset (core->bin);
	RBinObject *o = r_bin_cur_object (core->bin);
	RCoreFile *cf = core->file;

	int va = core->io->va || core->io->debug;
	int mode = 0; //R_CORE_BIN_SIMPLE;
	int is_array = 0;
	Sdb *db;

	if (strchr (input, '*'))
		mode = R_CORE_BIN_RADARE;
	if (strchr (input, 'j'))
		mode = R_CORE_BIN_JSON;

	if (mode == R_CORE_BIN_JSON) {
		if (strlen (input+1)>1)
			is_array = 1;
	}
	if (is_array)
		r_cons_printf ("{");
	if (!*input)
		cmd_info_bin (core, offset, va, mode);
	while (*input) {
		switch (*input) {
		case 'b':
			{
			ut64 baddr = r_config_get_i (core->config, "bin.baddr");
			if (input[1]==' ')
				baddr = r_num_math (core->num, input+1);
			// XXX: this will reload the bin using the buffer.
			// An assumption is made that assumes there is an underlying
			// plugin that will be used to load the bin (e.g. malloc://)
			// TODO: Might be nice to reload a bin at a specified offset?
			r_core_bin_reload (core, NULL, baddr);
			r_core_block_read (core, 0);
			}
			break;
		case 'k':
			db = o ? o->kv : NULL;
			//:eprintf ("db = %p\n", db);
			switch (input[1]) {
			case 'v':
				if (db) sdb_query (db, input+3);
				break;
			case '.':
			case ' ':
				if (db) sdb_query (db, input+2);
				break;
			case '\0':
				if (db) sdb_list (db);
				break;
			case '?':
			default:
				eprintf ("Usage: ik [sdb-query]\n");
			}
			break;
		case 'o': 
			 {
				const char *fn = input[1]==' '? input+2: cf->desc->name;
				ut64 laddr = UT64_MAX;
				laddr = r_config_get_i (core->config, "bin.baddr");
				r_core_bin_load (core, fn, laddr);
			 }
			break;
	#define RBININFO(n,x) \
	if (is_array) { \
		if (is_array==1) is_array++; else r_cons_printf (","); \
		r_cons_printf ("\"%s\":",n); \
	}\
	r_core_bin_info (core,x,mode,va,NULL,offset,NULL);
		case 'A': newline=0; r_bin_list_archs (core->bin, 1); break;
		case 'Z': RBININFO ("size",R_CORE_BIN_ACC_SIZE); break;
		case 'S': RBININFO ("sections",R_CORE_BIN_ACC_SECTIONS); break;
		case 'h': RBININFO ("fields", R_CORE_BIN_ACC_FIELDS); break;
		case 'l': RBININFO ("libs", R_CORE_BIN_ACC_LIBS); break;
		case 's': RBININFO ("symbols", R_CORE_BIN_ACC_SYMBOLS); break;
		case 'R':
		case 'r': RBININFO ("relocs", R_CORE_BIN_ACC_RELOCS); break;
		case 'd': RBININFO ("dwarf", R_CORE_BIN_ACC_DWARF); break;
		case 'i': RBININFO ("imports",R_CORE_BIN_ACC_IMPORTS); break;
		case 'I': RBININFO ("info", R_CORE_BIN_ACC_INFO); break;
		case 'e': RBININFO ("entries",R_CORE_BIN_ACC_ENTRIES); break;
		case 'z': RBININFO ("strings",R_CORE_BIN_ACC_STRINGS); break;
		case 'c':
		case 'C': RBININFO ("classes",R_CORE_BIN_ACC_CLASSES); break;
		case 'a':
			{
				switch (mode) {
				case R_CORE_BIN_RADARE: cmd_info (core, "i*IiesSz"); break;
				case R_CORE_BIN_JSON: cmd_info (core, "iIiesSzj"); break;
				default:
				case R_CORE_BIN_SIMPLE: cmd_info (core, "iIiesSz"); break;
				}
			}
			break;
		case '?': {
				const char * help_message[] = {
				"Usage: i", "", "Get info from opened file",
				"Output mode:", "", "",
				"'*'", "", "Output in radare commands",
				"'j'", "", "Output in json",
				"'q'", "", "Simple quiet output",
				"Actions:", "", "",
				"i|ij", "", "Show info of current file (in JSON)",
				"iA", "", "List archs",
				"ia", "", "Show all info (imports, exports, sections..)",
				"ib", "", "Reload the current buffer for setting of the bin (use once only)",
				"ic", "", "List classes",
				"id", "", "Debug information (source lines)",
				"ie", "", "Entrypoint",
				"ih", "", "Headers",
				"ii", "", "Imports",
				"iI", "", "Binary info",
				"ik", " [query]", "Key-value database from RBinObject",
				"il", "", "Libraries",
				"io", " [file]", "Load info from file (or last opened) use bin.baddr",
				"ir|iR", "", "Relocs",
				"is", "", "Symbols",
				"iS", "", "Sections",
				"iz", "", "Strings",
				NULL
				};
				r_core_cmd_help(core, help_message);

				}
			goto done;
		case '*':
			mode = R_CORE_BIN_RADARE;
			goto done;
		case 'j':
			mode = R_CORE_BIN_JSON;
			cmd_info_bin (core, offset, va, mode);
			goto done;
		default:
			cmd_info_bin (core, offset, va, mode);
			break;
		}
		input++;
		if (!strcmp (input, "j"))
			break;
	}
done:
	if (is_array)
		r_cons_printf ("}\n");
	if (newline) r_cons_newline();
	return 0;
}
Beispiel #6
0
static RList *patch_relocs(RBin *b) {
	struct r_bin_bflt_obj *bin = NULL;
	RList *list = NULL;
	RBinObject *obj;
	int i = 0;
	if (!b || !b->iob.io || !b->iob.io->desc) {
		return NULL;
	}
	if (!(b->iob.io->cached & R_PERM_W)) {
		eprintf (
			"Warning: please run r2 with -e io.cache=true to patch "
			"relocations\n");
		return list;
	}

	obj = r_bin_cur_object (b);
	if (!obj) {
		return NULL;
	}
	bin = obj->bin_obj;
	list = r_list_newf ((RListFree) free);
	if (!list) {
		return NULL;
	}
	if (bin->got_table) {
		struct reloc_struct_t *got_table = bin->got_table;
		for (i = 0; i < bin->n_got; i++) {
			__patch_reloc (bin->b, got_table[i].addr_to_patch,
				got_table[i].data_offset);
			RBinReloc *reloc = R_NEW0 (RBinReloc);
			if (reloc) {
				reloc->type = R_BIN_RELOC_32;
				reloc->paddr = got_table[i].addr_to_patch;
				reloc->vaddr = reloc->paddr;
				r_list_append (list, reloc);
			}
		}
		R_FREE (bin->got_table);
	}

	if (bin->reloc_table) {
		struct reloc_struct_t *reloc_table = bin->reloc_table;
		for (i = 0; i < bin->hdr->reloc_count; i++) {
			int found = search_old_relocation (reloc_table,
				reloc_table[i].addr_to_patch,
				bin->hdr->reloc_count);
			if (found != -1) {
				__patch_reloc (bin->b, reloc_table[found].addr_to_patch,
					reloc_table[i].data_offset);
			} else {
				__patch_reloc (bin->b, reloc_table[i].addr_to_patch,
					reloc_table[i].data_offset);
			}
			RBinReloc *reloc = R_NEW0 (RBinReloc);
			if (reloc) {
				reloc->type = R_BIN_RELOC_32;
				reloc->paddr = reloc_table[i].addr_to_patch;
				reloc->vaddr = reloc->paddr;
				r_list_append (list, reloc);
			}
		}
		R_FREE (bin->reloc_table);
	}
	b->iob.write_at (b->iob.io, bin->b->base, bin->b->buf, r_buf_size (bin->b));
	return list;
}
Beispiel #7
0
static int cmd_info(void *data, const char *input) {
	RCore *core = (RCore *)data;
	int newline = r_config_get_i (core->config, "scr.interactive");
	ut64 offset = r_bin_get_offset (core->bin);
	RBinObject *o = r_bin_cur_object (core->bin);
	RCoreFile *cf = core->file;

	int va = core->io->va || core->io->debug;
	int mode = 0; //R_CORE_BIN_SIMPLE;
	int is_array = 0;
	Sdb *db;

	if (strchr (input, '*'))
		mode = R_CORE_BIN_RADARE;
	if (strchr (input, 'j'))
		mode = R_CORE_BIN_JSON;

	if (mode == R_CORE_BIN_JSON) {
		if (strlen (input+1)>1)
			is_array = 1;
	}
	if (is_array)
		r_cons_printf ("{");
	if (!*input)
		cmd_info_bin (core, offset, va, mode);
	while (*input) {
		switch (*input) {
		case 'b':
			{
			ut64 baddr = r_config_get_i (core->config, "bin.baddr");
			if (input[1]==' ')
				baddr = r_num_math (core->num, input+1);
			// XXX: this will reload the bin using the buffer.
			// An assumption is made that assumes there is an underlying
			// plugin that will be used to load the bin (e.g. malloc://)
			// TODO: Might be nice to reload a bin at a specified offset?
			r_core_bin_reload (core, NULL, baddr);
			r_core_block_read (core, 0);
			}
			break;
		case 'k':
			db = o ? o->kv : NULL;
			//:eprintf ("db = %p\n", db);
			switch (input[1]) {
			case 'v':
				if (db) sdb_query (db, input+3);
				break;
			case '.':
			case ' ':
				if (db) sdb_query (db, input+2);
				break;
			case '\0':
				if (db) sdb_list (db);
				break;
			case '?':
			default:
				eprintf ("Usage: ik [sdb-query]\n");
			}
			break;
		case 'o': r_core_bin_load (core, input[1]==' '?
				input+2: cf->filename,
				r_config_get_i (core->config, "bin.baddr"));
			break;
	#define RBININFO(n,x) \
	if (is_array) { \
		if (is_array==1) is_array++; else r_cons_printf (","); \
		r_cons_printf ("\"%s\":",n); \
	}\
	r_core_bin_info (core,x,mode,va,NULL,offset);
		case 'A': newline=0; r_bin_list_archs (core->bin, 1); break;
		case 'S': RBININFO ("sections",R_CORE_BIN_ACC_SECTIONS); break;
		case 'h': RBININFO ("fields", R_CORE_BIN_ACC_FIELDS); break;
		case 'l': RBININFO ("libs", R_CORE_BIN_ACC_LIBS); break;
		case 's': RBININFO ("symbols", R_CORE_BIN_ACC_SYMBOLS); break;
		case 'R':
		case 'r': RBININFO ("relocs", R_CORE_BIN_ACC_RELOCS); break;
		case 'd': RBININFO ("dwarf", R_CORE_BIN_ACC_DWARF); break;
		case 'i': RBININFO ("imports",R_CORE_BIN_ACC_IMPORTS); break;
		case 'I': RBININFO ("info", R_CORE_BIN_ACC_INFO); break;
		case 'e': RBININFO ("entries",R_CORE_BIN_ACC_ENTRIES); break;
		case 'z': RBININFO ("strings",R_CORE_BIN_ACC_STRINGS); break;
		case 'c':
		case 'C': RBININFO ("classes",R_CORE_BIN_ACC_CLASSES); break;
		case 'a':
			{
				switch (mode) {
				case R_CORE_BIN_RADARE: cmd_info (core, "i*IiesSz"); break;
				case R_CORE_BIN_JSON: cmd_info (core, "ijIiesSz"); break;
				default:
				case R_CORE_BIN_SIMPLE: cmd_info (core, "iIiesSz"); break;
				}
			}
			break;
		case '?':
			r_cons_printf (
			"|Usage: i[aeciIsosSz][jq*]      ; get info from opened file\n"
			"|Output mode:\n"
			"| '*'   output in radare commands\n"
			"| 'j'   output in json\n"
			"| 'q'   simple quiet output\n"
			"|Actions:\n"
			"| i, ij       show info of current file (in JSON)\n"
			"| iA          list archs\n"
			"| ia          show all info (imports, exports, sections..)\n"
			"| ib          reload the current buffer for setting of the bin (use once only)\n"
			"| ic          list classes\n"
			"| id          debug information (source lines)\n"
			"| ie          entrypoint\n"
			"| ih          headers\n"
			"| ii          imports\n"
			"| iI          binary info\n"
			"| il          libraries\n"
			"| ik [query]  key-value database from RBinObject\n"
			"| io [file]   load info from file (or last opened) use bin.baddr\n"
			"| is          symbols\n"
			"| iS          sections\n"
			"| ir/iR       relocs\n"
			"| iz          strings\n"
			);
			goto done;
		case '*':
			mode = R_CORE_BIN_RADARE;
			goto done;
		case 'j':
			mode = R_CORE_BIN_JSON;
			cmd_info_bin (core, offset, va, mode);
			goto done;
		default:
			cmd_info_bin (core, offset, va, mode);
			break;
		}
		input++;
		if (!strcmp (input, "j"))
			break;
	}
done:
	if (is_array)
		r_cons_printf ("}\n");
	if (newline) r_cons_newline();
	return 0;
}