コード例 #1
0
ファイル: var.c プロジェクト: monosource/radare2
R_API int r_anal_var_retype(RAnal *a, ut64 addr, int scope, int delta, char kind, const char *type, int size, const char *name) {
	char *var_def;
	RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
	if (!kind) {
		kind = R_ANAL_VAR_KIND_BPV;
	}
	if (!type) {
		type = "int";
	}
	if (!a || !fcn) {
		return false;
	}
	if (size == -1) {
		RList *list = r_anal_var_list (a, fcn, kind);
		RListIter *iter;
		RAnalVar *var;
		r_list_foreach (list, iter, var) {
			if (delta == -1) {
				if (!strcmp (var->name, name)) {
					delta = var->delta;
					size = var->size;
					break;
				}
			}
		}
		r_list_free (list);
	}
コード例 #2
0
ファイル: visual.c プロジェクト: xuwenbo/radare2
R_API int r_core_visual_xrefs_x (RCore *core) {
	int ret = 0;
#if FCN_OLD
	char ch;
	int count = 0;
	RList *xrefs = NULL;
	RAnalRef *refi;
	RListIter *iter;
	RAnalFunction *fun;

	if ((xrefs = r_anal_xref_get (core->anal, core->offset))) {
		r_cons_gotoxy (1, 1);
		r_cons_printf ("[GOTO XREF]> \n");
		if (r_list_empty (xrefs)) {
			r_cons_printf ("\tNo XREF found at 0x%"PFMT64x"\n", core->offset);
			r_cons_any_key (NULL);
			r_cons_clear00 ();
		} else {
			r_list_foreach (xrefs, iter, refi) {
				fun = r_anal_get_fcn_in (core->anal, refi->addr, R_ANAL_FCN_TYPE_NULL);
				r_cons_printf (" [%i] 0x%08"PFMT64x" %s XREF 0x%08"PFMT64x" (%s)                      \n", count,
					refi->at,
					      refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
					      refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
					      fun?fun->name:"unk");
				if (++count > 9) break;
			}
		}
コード例 #3
0
ファイル: var.c プロジェクト: earada/radare2
R_API RAnalVar *r_anal_var_get (RAnal *a, ut64 addr, char kind, int scope, int delta) {
	RAnalVar *av;
	struct VarType vt;
	RAnalFunction *fcn = r_anal_get_fcn_in (a, addr, 0);
	if (!fcn)
		return NULL;
	if (delta<0) {
		kind = 'v';
		delta = -delta;
	}
	char *vardef = sdb_get (DB,
		sdb_fmt (0, "var.0x%"PFMT64x".%c.%d.%d",
			fcn->addr, kind, scope, delta), 0);
	if (!vardef)
		return NULL;
	sdb_fmt_tobin (vardef, SDB_VARTYPE_FMT, &vt);

	av = R_NEW0 (RAnalVar);
	av->addr = addr;
	av->scope = scope;
	av->delta = delta;
	av->name = strdup (vt.name);
	av->size = vt.size;
	av->type = strdup (vt.type);

	sdb_fmt_free (&vt, SDB_VARTYPE_FMT);
	// TODO:
	// get name from sdb
	// get size from sdb
	// get type from sdb
	return av;
}
コード例 #4
0
ファイル: cmd_meta.c プロジェクト: AnwarMohamed/radare2
static int cmd_meta(void *data, const char *input) {
	RCore *core = (RCore*)data;
	int i;
	RAnalFunction *f;

	switch (*input) {
	case 'j':
	case '*':
		r_meta_list (core->anal, R_META_TYPE_ANY, *input);
		break;
	case 'L':
		cmd_meta_lineinfo (core, input + 1);
		break;
	case 'C':
		cmd_meta_comment (core, input);
		break;
	case 'h': /* comment */
	case 's': /* string */
	case 'd': /* data */
	case 'm': /* magic */
	case 'f': /* formatted */
		cmd_meta_hsdmf (core, input);
		break;
	case '-':
		if (input[1]!='*') {
			i = r_num_math (core->num, input+((input[1]==' ')?2:1));
			r_meta_del (core->anal, R_META_TYPE_ANY, core->offset, i, "");
		} else r_meta_cleanup (core->anal, 0LL, UT64_MAX);
		break;
	case '\0':
	case '?':{
			const char* help_msg[] = {
				"Usage:", "C[-LCvsdfm?] [...]", " # Metadata management",
				"C*", "", "list meta info in r2 commands",
				"C-", " [len] [[@]addr]", "delete metadata at given address range",
				"CL", "[-][*] [file:line] [addr]", "show or add 'code line' information (bininfo)",
				"CC", "[-] [comment-text] [@addr]", "add/remove comment",
				"CC!", " [@addr]", "edit comment with $EDITOR",
				"CCa", "[-at]|[at] [text] [@addr]", "add/remove comment at given address",
				"CCu", " [comment-text] [@addr]", "add unique comment",
				"Cs", "[-] [size] [@addr]", "add string",
				"Ch", "[-] [size] [@addr]", "hide data",
				"Cd", "[-] [size] [@addr]", "hexdump data",
				"Cf", "[-] [sz] [fmt..] [@addr]", "format memory (see pf?)",
				"Cm", "[-] [sz] [fmt..] [@addr]", "magic parse (see pm?)",
				NULL};
			r_core_cmd_help (core, help_msg);
			}
		break;
	case 'F':
		f = r_anal_get_fcn_in (core->anal, core->offset,
			R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
		if (f) r_anal_str_to_fcn (core->anal, f, input+2);
		else eprintf ("Cannot find function here\n");
		break;
	}
	return R_TRUE;
}
コード例 #5
0
ファイル: anal_tp.c プロジェクト: Lukas-Dresel/radare2
R_API void r_anal_type_match(RCore *core, RAnalFunction *fcn) {
	bool esil_var[STATES_SIZE] = {false};
	if (!core ) {
		return;
	}
	if (!r_anal_emul_init (core, esil_var) || !fcn ) {
		r_anal_emul_restore (core, esil_var);
		return;
	}
	const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC);
	ut64 addr = fcn->addr;
	r_reg_setv (core->dbg->reg, pc, fcn->addr);
	r_debug_reg_sync (core->dbg, -1, true);
	r_cons_break (NULL, NULL);
	while (!r_cons_is_breaked ()) {
		RAnalOp *op = r_core_anal_op (core, addr);
		int loop_count = sdb_num_get ( core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), 0);
		if (loop_count > LOOP_MAX) {
			eprintf ("Unfortunately your evilly engineered %s function trapped my most innocent `aftm` in an infinite loop.\n", fcn->name);
			eprintf ("I kept trace log for you to review and find out how bad things were going to happen by yourself.\n");
			eprintf ("You can view this log by `ate`. Meanwhile, I will train on how to behave with such behaviour without bothering you.\n");
			return;
		}
		sdb_num_set (core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), loop_count + 1, 0);
		if (!op || op->type == R_ANAL_OP_TYPE_RET) {
			r_anal_emul_restore (core, esil_var);
			return;
		}
		if (op->type == R_ANAL_OP_TYPE_CALL) {
			RAnalFunction *fcn_call = r_anal_get_fcn_in (core->anal, op->jump, -1);
			//eprintf ("in the middle of %s\n", fcn_call->name);
			if (fcn_call) {
				type_match (core, addr, fcn_call->name);
			} else {
				eprintf ("Cannot find function at 0x%08"PFMT64x"\n", op->jump);
			}
			addr += op->size;
			r_anal_op_free (op);
			r_reg_setv (core->dbg->reg, pc, addr);
			r_debug_reg_sync (core->dbg, -1, true);
			r_anal_esil_set_pc (core->anal->esil, addr);
			addr += stack_clean (core, addr, fcn);
			r_reg_setv (core->dbg->reg, pc, addr);
			r_debug_reg_sync (core->dbg, -1, true);
			r_anal_esil_set_pc (core->anal->esil, addr);
			continue;
		} else {
			r_core_esil_step (core, UT64_MAX, NULL);
			r_anal_op_free (op);
		}
		r_core_cmd0 (core, ".ar*");
		addr = r_reg_getv (core->anal->reg, pc);
	}
	r_cons_break_end ();
	r_anal_emul_restore (core, esil_var);

}
コード例 #6
0
ファイル: generic-x64.c プロジェクト: PankajKataria/radare2
// XXX: Do this work correctly?
static RList *backtrace_x86_64_anal(RDebug *dbg, ut64 at) {
	int i;
	ut8 buf[8];
	RDebugFrame *frame;
	ut64 ptr, ebp2 = UT64_MAX;
	ut64 _rip, _rbp;
	RList *list;
	RReg *reg = dbg->reg;
	RIOBind *bio = &dbg->iob;
	RAnalFunction *fcn;

	_rip = r_reg_get_value (reg, r_reg_get (reg, "rip", R_REG_TYPE_GPR));
	if (at == UT64_MAX) {
		//_rsp = r_reg_get_value (reg, r_reg_get (reg, "rsp", R_REG_TYPE_GPR));
		_rbp = r_reg_get_value (reg, r_reg_get (reg, "rbp", R_REG_TYPE_GPR));
	} else {
		_rbp = at;
	}

	list = r_list_new ();
	list->free = free;
	bio->read_at (bio->io, _rip, (ut8*)&buf, 8);

	// TODO : frame->size by using esil to emulate first instructions
	fcn = r_anal_get_fcn_in (dbg->anal, _rip, R_ANAL_FCN_TYPE_NULL);
	if (fcn) {
		frame = R_NEW0 (RDebugFrame);
		frame->addr = _rip;
		frame->size = 0;
		frame->sp = _rbp;
		frame->bp = _rbp + 8; // XXX
		r_list_append (list, frame);
	}

	for (i=1; i<dbg->btdepth; i++) {
		// TODO: make those two reads in a shot
		bio->read_at (bio->io, _rbp, (ut8*)&ebp2, 8);
		if (ebp2 == UT64_MAX)
			break;
		bio->read_at (bio->io, _rbp+8, (ut8*)&ptr, 8);
		if (!ptr || !_rbp)
			break;
		//fcn = r_anal_get_fcn_in (dbg->anal, ptr, R_ANAL_FCN_TYPE_NULL);
		frame = R_NEW0 (RDebugFrame);
		frame->addr = ptr;
		frame->size = 0;
		frame->sp = _rbp;
		frame->bp = _rbp + 8;
		//frame->name = (fcn && fcn->name) ? strdup (fcn->name) : NULL;
		r_list_append (list, frame);
		_rbp = ebp2;
	}

	return list;
}
コード例 #7
0
ファイル: core.c プロジェクト: 0x2F/radare2
static ut64 getref (RCore *core, int n, char t, int type) {
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
	RListIter *iter;
	RAnalRef *r;
	RList *list;
	int i=0;
	if (!fcn) return UT64_MAX;
#if FCN_OLD
	list = (t=='r')? fcn->refs: fcn->xrefs;
	r_list_foreach (list, iter, r) {
		if (r->type == type) {
			if (i == n)
				return r->addr;
			i++;
		}
	}
#else
#warning implement getref() using sdb
#endif
	return UT64_MAX;
}
コード例 #8
0
ファイル: core.c プロジェクト: 0x2F/radare2
static ut64 num_callback(RNum *userptr, const char *str, int *ok) {
	RCore *core = (RCore *)userptr; // XXX ?
	RAnalFunction *fcn;
	char *ptr, *bptr, *out;
	RFlagItem *flag;
	RIOSection *s;
	RAnalOp op;
	ut64 ret = 0;

	if (ok) *ok = R_FALSE;
	switch (*str) {
	case '[':
{
		ut64 n = 0LL;
		int refsz = (core->assembler->bits & R_SYS_BITS_64)? 8: 4;
		const char *p = NULL;
		if (strlen (str)>5)
			p = strchr (str+5, ':');
		// TODO: honor LE
		if (p) {
			refsz = atoi (str+1);
			str = p;
		}
		// push state
		{
			if (str[0] && str[1]) {
				const char *q;
				char *o = strdup (str+1);
				if (o) {
					q = r_num_calc_index (core->num, NULL);
					if (q) {
						if (r_str_replace_char (o, ']', 0)>0) {
							n = r_num_math (core->num, o);
							r_num_calc_index (core->num, q);
						}
					}
					free (o);
				}
			}
		}
		// pop state
		if (ok) *ok = 1;
		ut32 num = 0;
		switch (refsz) {
		case 8:
		case 4:
		case 2:
		case 1:
			(void)r_io_read_at (core->io, n, (ut8*)&num, refsz);
			r_mem_copyendian ((ut8*)&num, (ut8*)&num, refsz, !core->assembler->big_endian);
			return num;
		default:
			eprintf ("Invalid reference size: %d (%s)\n", refsz, str);
			return 0LL;
		}
}
		break;
	case '$':
		if (ok) *ok = 1;
		// TODO: group analop-dependant vars after a char, so i can filter
		r_anal_op (core->anal, &op, core->offset,
			core->block, core->blocksize);
		switch (str[1]) {
		case '.': // can use pc, sp, a0, a1, ...
			return r_debug_reg_get (core->dbg, str+2);
		case 'k':
			if (str[2]!='{') {
				eprintf ("Expected '{' after 'k'.\n");
				break;
			}
			bptr = strdup (str+3);
			ptr = strchr (bptr, '}');
			if (ptr == NULL) {
				// invalid json
				free (bptr);
				break;
			}
			*ptr = '\0';
			ret = 0LL;
			out = sdb_querys (core->sdb, NULL, 0, bptr);
			if (out && *out) {
				if (strstr (out, "$k{")) {
					eprintf ("Recursivity is not permitted here\n");
				} else {
					ret = r_num_math (core->num, out);
				}
			}
			free (bptr);
			free (out);
			return ret;
			break;
		case '{':
			bptr = strdup (str+2);
			ptr = strchr (bptr, '}');
			if (ptr != NULL) {
				ut64 ret;
				ptr[0] = '\0';
				ret = r_config_get_i (core->config, bptr);
				free (bptr);
				return ret;
			}
			free (bptr);
			break;
		case 'c': return r_cons_get_size (NULL);
		case 'r': { int rows; r_cons_get_size (&rows); return rows; }
		case 'e': return r_anal_op_is_eob (&op);
		case 'j': return op.jump;
		case 'p': return r_sys_getpid ();
		case 'P': return (core->dbg->pid>0)? core->dbg->pid: 0;
		case 'f': return op.fail;
		case 'm': return op.ptr; // memref
		case 'v': return op.val; // immediate value
		case 'l': return op.size;
		case 'b': return core->blocksize;
		case 's':
			if (core->file) {
				return r_io_desc_size (core->io, core->file->desc);
			}
			return 0LL;
		case 'w': return r_config_get_i (core->config, "asm.bits") / 8;
		case 'S':
			s = r_io_section_vget (core->io, core->offset);
			return s? (str[2]=='S'? s->size: s->vaddr): 3;
		case '?': return core->num->value;
		case '$': return core->offset;
		case 'o': return r_io_section_vaddr_to_offset (core->io,
				core->offset);
		case 'C': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CALL);
		case 'J': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_CODE);
		case 'D': return getref (core, atoi (str+2), 'r',
				R_ANAL_REF_TYPE_DATA);
		case 'X': return getref (core, atoi (str+2), 'x',
				R_ANAL_REF_TYPE_CALL);
		case 'I':
			fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->ninstr: 0;
		case 'F':
			fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			return fcn? fcn->size: 0;
		}
		break;
	default:
		if (*str>'A') {
			// NOTE: functions override flags
			RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, str);
			if (fcn) {
				if (ok) *ok = R_TRUE;
				return fcn->addr;
			}
#if 0
			ut64 addr = r_anal_fcn_label_get (core->anal, core->offset, str);
			if (addr != 0) {
				ret = addr;
			} else {
				...
			}
#endif
			if ((flag = r_flag_get (core->flags, str))) {
				ret = flag->offset;
				if (ok) *ok = R_TRUE;
			}
		}
		break;
	}
コード例 #9
0
ファイル: cmd_meta.c プロジェクト: 8500616886/radare2
static int cmd_meta(void *data, const char *input) {
	RCore *core = (RCore*)data;
	int i;
	RAnalFunction *f;

	switch (*input) {
	case 'j':
	case '*':
		r_meta_list (core->anal, R_META_TYPE_ANY, *input);
		break;
	case 'L':
		cmd_meta_lineinfo (core, input + 1);
		break;
	case 'C':
		cmd_meta_comment (core, input);
		break;
	case 'h': /* comment */
	case 's': /* string */
	case 'd': /* data */
	case 'm': /* magic */
	case 'f': /* formatted */
		cmd_meta_hsdmf (core, input);
		break;
	case '-':
		if (input[1]!='*') {
			i = r_num_math (core->num, input+((input[1]==' ')?2:1));
			r_meta_del (core->anal, R_META_TYPE_ANY, core->offset, i, "");
		} else r_meta_cleanup (core->anal, 0LL, UT64_MAX);
		break;
	case '\0':
	case '?':{
			const char* help_msg[] = {
				"Usage:", "C[-LCvsdfm?] [...]", " # Metadata management",
				"C*", "", "list meta info in r2 commands",
				"C-", " [len] [[@]addr]", "delete metadata at given address range",
				"CL", "[-][*] [file:line] [addr]", "show or add 'code line' information (bininfo)",
				"CS", "[-][space]", "manage meta-spaces to filter comments, etc..",
				"CC", "[-] [comment-text] [@addr]", "add/remove comment",
				"CC!", " [@addr]", "edit comment with $EDITOR",
				"CCa", "[-at]|[at] [text] [@addr]", "add/remove comment at given address",
				"CCu", " [comment-text] [@addr]", "add unique comment",
				"Cs", "[-] [size] [@addr]", "add string",
				"Ch", "[-] [size] [@addr]", "hide data",
				"Cd", "[-] [size] [@addr]", "hexdump data",
				"Cf", "[-] [sz] [fmt..] [@addr]", "format memory (see pf?)",
				"Cm", "[-] [sz] [fmt..] [@addr]", "magic parse (see pm?)",
				NULL};
			r_core_cmd_help (core, help_msg);
			}
		break;
	case 'F':
		f = r_anal_get_fcn_in (core->anal, core->offset,
			R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
		if (f) r_anal_str_to_fcn (core->anal, f, input+2);
		else eprintf ("Cannot find function here\n");
		break;
	case 'S':
		 {
		RSpaces *ms = &core->anal->meta_spaces;
		/** copypasta from `fs`.. this must be refactorized to be shared */
		switch (input[1]) {
		case '?':
			{
			const char *help_msg[] = {
			"Usage: CS","[*] [+-][metaspace|addr]", " # Manage metaspaces",
			"CS","","display metaspaces",
			"CS"," *","select all metaspaces",
			"CS"," metaspace","select metaspace or create if it doesn't exist",
			"CS","-metaspace","remove metaspace",
			"CS","-*","remove all metaspaces",
			"CS","+foo","push previous metaspace and set",
			"CS","-","pop to the previous metaspace",
		//	"CSm"," [addr]","move metas at given address to the current metaspace",
			"CSr"," newname","rename selected metaspace",
			NULL};
			r_core_cmd_help (core, help_msg);
			}
			break;
		case '+':
			r_space_push (ms, input+2);
			break;
		case 'r':
			if (input[2]==' ')
				r_space_rename (ms, NULL, input+2);
			else eprintf ("Usage: CSr [newname]\n");
			break;
		case '-':
			if (input[2]) {
				if (input[2]=='*') {
					r_space_unset (ms, NULL);
				} else {
					r_space_unset (ms, input+2);
				}
			} else {
				r_space_pop (ms);
			}
			break;
		case 'j':
		case '\0':
		case '*':
			r_space_list (ms, input[1]);
			break;
		case ' ':
			r_space_set (ms, input+2);
			break;
#if 0
		case 'm':
			{ RFlagItem *f;
			ut64 off = core->offset;
			if (input[2] == ' ')
				off = r_num_math (core->num, input+2);
			f = r_flag_get_i (core->flags, off);
			if (f) {
				f->space = core->flags->space_idx;
			} else eprintf ("Cannot find any flag at 0x%"PFMT64x".\n", off);
			}
			break;
#endif
		default: {
			int i, j = 0;
			for (i=0; i<R_FLAG_SPACES_MAX; i++) {
				if (ms->spaces[i])
					r_cons_printf ("%02d %c %s\n", j++,
					(i==ms->space_idx)?'*':' ',
					ms->spaces[i]);
			}
			} break;
		}
		 }
		break;
	}
	return R_TRUE;
}
コード例 #10
0
ファイル: pseudo.c プロジェクト: P4N74/radare2
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;
}
コード例 #11
0
ファイル: op.c プロジェクト: commiebstrd/radare2
// TODO: use esil here?
R_API char *r_anal_op_to_string(RAnal *anal, RAnalOp *op) {
	RAnalFunction *f;
	char ret[128];
	char *cstr;
	char *r0 = r_anal_value_to_string (op->dst);
	char *a0 = r_anal_value_to_string (op->src[0]);
	char *a1 = r_anal_value_to_string (op->src[1]);

	switch (op->type) {
	case R_ANAL_OP_TYPE_MOV:
		snprintf (ret, sizeof (ret), "%s = %s", r0, a0);
		break;
	case R_ANAL_OP_TYPE_CJMP:
		{
		RAnalBlock *bb = r_anal_bb_from_offset (anal, op->addr);
		if (bb) {
			cstr = r_anal_cond_to_string (bb->cond);
			snprintf (ret, sizeof (ret), "if (%s) goto 0x%"PFMT64x, cstr, op->jump);
			free (cstr);
		} else snprintf (ret, sizeof (ret), "if (%s) goto 0x%"PFMT64x, "unk", op->jump);
		}
		break;
	case R_ANAL_OP_TYPE_JMP:
		snprintf (ret, sizeof (ret), "goto 0x%"PFMT64x, op->jump);
		break;
	case R_ANAL_OP_TYPE_UJMP:
		snprintf (ret, sizeof (ret), "goto %s", r0);
		break;
	case R_ANAL_OP_TYPE_PUSH:
	case R_ANAL_OP_TYPE_UPUSH:
		snprintf (ret, sizeof (ret), "push %s", a0);
		break;
	case R_ANAL_OP_TYPE_POP:
		snprintf (ret, sizeof (ret), "pop %s", r0);
		break;
	case R_ANAL_OP_TYPE_UCALL:
		snprintf (ret, sizeof (ret), "%s()", r0);
		break;
	case R_ANAL_OP_TYPE_CALL:
		f = r_anal_get_fcn_in (anal, op->jump, R_ANAL_FCN_TYPE_NULL);
		if (f) snprintf (ret, sizeof (ret), "%s()", f->name);
		else  snprintf (ret, sizeof (ret), "0x%"PFMT64x"()", op->jump);
		break;
	case R_ANAL_OP_TYPE_CCALL:
		f = r_anal_get_fcn_in (anal, op->jump, R_ANAL_FCN_TYPE_NULL);
		{
		RAnalBlock *bb = r_anal_bb_from_offset (anal, op->addr);
		if (bb) {
			cstr = r_anal_cond_to_string (bb->cond);
			if (f) snprintf (ret, sizeof (ret), "if (%s) %s()", cstr, f->name);
			else snprintf (ret, sizeof (ret), "if (%s) 0x%"PFMT64x"()", cstr, op->jump);
			free (cstr);
		} else {
			if (f) snprintf (ret, sizeof (ret), "if (unk) %s()", f->name);
			else snprintf (ret, sizeof (ret), "if (unk) 0x%"PFMT64x"()", op->jump);
		}
		}
		break;
	case R_ANAL_OP_TYPE_ADD:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s += %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s + %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_SUB:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s -= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s - %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_MUL:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s *= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s * %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_DIV:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s /= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s / %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_AND:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s &= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s & %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_OR:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s |= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s | %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_XOR:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s ^= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s ^ %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_LEA:
		snprintf (ret, sizeof (ret), "%s -> %s", r0, a0);
		break;
	case R_ANAL_OP_TYPE_CMP:
		memcpy (ret, ";", 2);
		break;
	case R_ANAL_OP_TYPE_NOP:
		memcpy (ret, "nop", 4);
		break;
	case R_ANAL_OP_TYPE_RET:
		memcpy (ret, "ret", 4);
		break;
	case R_ANAL_OP_TYPE_CRET:
		{
		RAnalBlock *bb = r_anal_bb_from_offset (anal, op->addr);
		if (bb) {
			cstr = r_anal_cond_to_string (bb->cond);
			snprintf (ret, sizeof (ret), "if (%s) ret", cstr);
			free (cstr);
		} else memcpy (ret, "if (unk) ret", 13);
		}
		break;
	case R_ANAL_OP_TYPE_LEAVE:
		memcpy (ret, "leave", 6);
		break;
	case R_ANAL_OP_TYPE_MOD:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "%s %%= %s", r0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s %% %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_XCHG:
		if (a1 == NULL || !strcmp (a0, a1))
			snprintf (ret, sizeof (ret), "tmp = %s; %s = %s; %s = tmp", r0, r0, a0, a0);
		else snprintf (ret, sizeof (ret), "%s = %s ^ %s", r0, a0, a1);
		break;
	case R_ANAL_OP_TYPE_ROL:
	case R_ANAL_OP_TYPE_ROR:
	case R_ANAL_OP_TYPE_SWITCH:
	case R_ANAL_OP_TYPE_CASE:
		eprintf ("Command not implemented.\n");
		free (r0);
		free (a0);
		free (a1);
		return NULL;
	default:
		free (r0);
		free (a0);
		free (a1);
		return NULL;
	}
	free (r0);
	free (a0);
	free (a1);
	return strdup (ret);
}
コード例 #12
0
ファイル: pseudo.c プロジェクト: 8500616886/radare2
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;
}
コード例 #13
0
ファイル: cc.c プロジェクト: DePierre/radare2
// XXX: RVM must be inside RAnal ???? imho no. rsyscall must provide ret reg info
//XXX: may overflow. this is vulnerable. needs fix
R_API char *r_anal_cc_to_string (RAnal *anal, RAnalCC* cc) {
	RSyscallItem *si;
	RAnalFunction *fcn;
	char str[1024], buf[64];
	int i, eax = 0; // eax = arg0
	int str_len = 0;
	int buf_len = 0;

	str[0] = 0;
	switch (cc->type) {
	case R_ANAL_CC_TYPE_FASTCALL: // INT
		{
		RRegItem *item;
		const char *a0 = r_reg_get_name (anal->reg, R_REG_NAME_A0); // A0 or RET ??
		item = r_reg_get (anal->reg, a0, R_REG_TYPE_GPR);
		if (!item) {
			//eprintf ("cannot get reg a0\n");
			return R_FALSE;
		}
		eax = (int)r_reg_get_value (anal->reg, item);
		si = r_syscall_get (anal->syscall, eax, (int)cc->jump);
		if (si) {
			//DEBUG r_cons_printf (" ; sc[0x%x][%d]=%s(", (int)analop.value, eax, si->name);
			snprintf (str, sizeof (str), "%s (", si->name);
			for (i=0; i<si->args; i++) {
				const char *reg = r_syscall_reg (anal->syscall, i+1, si->args);
				if (!reg) break; // no registers?
				item = r_reg_get (anal->reg, reg, R_REG_TYPE_GPR);
				if (item) {
					snprintf (buf, sizeof (buf), "0x%"PFMT64x, r_reg_get_value (anal->reg, item));
					strcat (str, buf); // XXX: do not use strcat
				} //else eprintf ("Unknown reg '%s'\n", reg);
				if (i<si->args-1)
					strcat (str, ","); // XXX: do not use strcat
			}
			strcat (str, ")");
		} else {
			int n = (int)cc->jump;
			//if (n == 3) return NULL; // XXX: hack for x86
			snprintf (str, sizeof (str), "syscall[0x%x][%d]=?", n, eax);
		}
		}
		break;
	case R_ANAL_CC_TYPE_CDECL:
		eprintf ("TODO\n");
		break;
	case R_ANAL_CC_TYPE_STDCALL: // CALL
		fcn = r_anal_get_fcn_in (anal, cc->jump,
				R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM|R_ANAL_FCN_TYPE_IMP);
		if (fcn && fcn->name)
			snprintf (str, sizeof (str), "%s(", fcn->name);
		else if (cc->jump != -1LL)
			snprintf (str, sizeof (str), "0x%08"PFMT64x"(", cc->jump);
		else strncpy (str, "unk(", sizeof (str)-1);
		str_len = strlen (str);
		if (fcn) cc->nargs = (fcn->nargs>cc->nargs?fcn->nargs:cc->nargs);
		if (cc->nargs>8) {
			//eprintf ("too many arguments for stdcall. chop to 8\n");
			cc->nargs = 8;
		}
		// TODO: optimize string concat
		for (i=0; i<cc->nargs; i++) {
			if (cc->args[cc->nargs-i] != -1LL)
				 snprintf (buf, sizeof (buf),
					"0x%"PFMT64x, cc->args[cc->nargs-i]);
			else strncpy (buf, "unk", sizeof (buf)-1);
			buf_len = strlen (buf);
			if ((buf_len+str_len+5)>=sizeof (str)) {
				strcat (str, "...");
				break;
			}
			strcat (str, buf);
			str_len += buf_len;
			if (i<cc->nargs-1) strcat (str, ", ");
		}
		strcat (str, ")");
		break;
	}
	return strdup (str);
}
コード例 #14
0
ファイル: cmd_seek.c プロジェクト: therealkbhat/radare2
static int cmd_seek(void *data, const char *input) {
	RCore *core = (RCore *)data;
	char *cmd, *p;
	ut64 off;

	if (*input == 'r') {
		if (input[1] && input[2]) {
			if (core->io->debug) {
				off = r_debug_reg_get (core->dbg, input + 2);
				r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				r_core_seek (core, off, 1);
			} else {
				RReg *orig = core->dbg->reg;
				core->dbg->reg = core->anal->reg;
				off = r_debug_reg_get (core->dbg, input + 2);
				core->dbg->reg = orig;
				r_core_seek (core, off, 1);
			}
		} else eprintf ("|Usage| 'sr PC' seek to program counter register\n");
	}
	if (*input) {
		char* ptr;
		if ((ptr = strstr(input, "+.")) != NULL) {
			char* dup = strdup(input);
			dup[ptr - input] = '\x00';
			off = r_num_math (core->num, dup + 1);
			core->offset = off;
			free (dup);
		}
		const char *inputnum = strchr (input, ' ');
		int sign = 1;
		{
			const char *u_num = inputnum? inputnum + 1: input + 1;
			off = r_num_math (core->num, u_num);
			if (*u_num == '-') off = -off;
		}
#if 0
		if (input[0]!='/' && inputnum && isalpha (inputnum[0]) && off == 0) {
			if (!r_flag_get (core->flags, inputnum)) {
				eprintf ("Cannot find address for '%s'\n", inputnum);
				return false;
			}
		}
#endif
		if (input[0]==' ') {
			switch (input[1]) {
			case '-': sign=-1;
			case '+': input++; break;
			}
		}

		switch (*input) {
		case 'C':
			if (input[1]=='*') {
				r_core_cmd0 (core, "C*~^\"CC");
			} else
			if (input[1]==' ') {
				typedef struct {
					ut64 addr;
					char *str;
				} MetaCallback;
				int count = 0;
				MetaCallback cb = { 0, NULL };
				ut64 addr;
				char key[128];
				const char *val, *comma;
				char *list = sdb_get (core->anal->sdb_meta, "meta.C", 0);
				char *str, *next, *cur = list;
				if (list) {
					for (;;) {
						cur = sdb_anext (cur, &next);
						addr = sdb_atoi (cur);
						snprintf (key, sizeof (key)-1, "meta.C.0x%"PFMT64x, addr);
						val = sdb_const_get (core->anal->sdb_meta, key, 0);
						if (val) {
							comma = strchr (val, ',');
							if (comma) {
								str = (char *)sdb_decode (comma+1, 0);
								if (strstr (str, input+2)) {
									r_cons_printf ("0x%08"PFMT64x"  %s\n", addr, str);
									count++;
									cb.addr = addr;
									free (cb.str);
									cb.str = str;
								} else free (str);
							}
						} else eprintf ("sdb_const_get key not found '%s'\n", key);
						if (!next)
							break;
						cur = next;
					}
				}

				switch (count) {
				case 0:
					eprintf ("No matching comments\n");
					break;
				case 1:
					off = cb.addr;
					r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
					r_core_seek (core, off, 1);
					r_core_block_read (core);
					break;
				default:
					eprintf ("Too many results\n");
					break;
				}
				free (cb.str);
			} else {
				const char *help_msg[] = {
					"Usage:", "sC", "Comment grep",
					"sC", "*", "List all comments",
					"sC", " str", "Seek to the first comment matching 'str'",
					NULL };
				r_core_cmd_help (core, help_msg);
			}
			break;
		case ' ':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek (core, off * sign, 1);
			r_core_block_read (core);
			break;
		case '/':
			{
			const char *pfx = r_config_get (core->config, "search.prefix");
			ut64 from = r_config_get_i (core->config, "search.from");
//kwidx cfg var is ignored
			int kwidx = core->search->n_kws; //(int)r_config_get_i (core->config, "search.kwidx")-1;
			if (kwidx<0) kwidx = 0;
			switch (input[1]) {
			case ' ':
			case 'v':
			case 'V':
			case 'w':
			case 'W':
			case 'z':
			case 'm':
			case 'c':
			case 'A':
			case 'e':
			case 'E':
			case 'i':
			case 'R':
			case 'r':
			case '/':
			case 'x':
				r_config_set_i (core->config, "search.from", core->offset+1);
				r_config_set_i (core->config, "search.count", 1);
				r_core_cmdf (core, "s+1; %s; s-1; s %s%d_0; f-%s%d_0",
					input, pfx, kwidx, pfx, kwidx, pfx, kwidx);
				r_config_set_i (core->config, "search.from", from);
				r_config_set_i (core->config, "search.count", 0);
				break;
			case '?':
				eprintf ("Usage: s/.. arg.\n");
				r_cons_printf ("/?\n");
				break;
			default:
				eprintf ("unknown search method\n");
				break;
			}
			}
			break;
		case '.':
			for (input++;*input=='.';input++);
			r_core_seek_base (core, input);
			break;
		case '*':
		case '=':
		case 'j':
			r_io_sundo_list (core->io, input[0]);
			break;
		case '+':
			if (input[1]!='\0') {
				int delta = (input[1]=='+')? core->blocksize: off;
				r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				r_core_seek_delta (core, delta);
			} else {
				RIOUndos *undo = r_io_sundo_redo (core->io);
				if (undo != NULL)
					r_core_seek (core, undo->off, 0);
			}
			break;
		case '-':
			if (input[1]!='\0') {
				int delta = (input[1]=='-') ? -core->blocksize: -off;
				r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
				r_core_seek_delta (core, delta);
			} else {
				RIOUndos *undo = r_io_sundo (core->io, core->offset);
				if (undo) {
					r_core_seek (core, undo->off, 0);
					r_core_block_read (core);
				}
			}
			break;
		case 'n':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek_next (core, r_config_get (core->config, "scr.nkey"));
			break;
		case 'p':
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek_previous (core, r_config_get (core->config, "scr.nkey"));
			break;
		case 'a':
			off = core->blocksize;
			if (input[1]&&input[2]) {
				cmd = strdup (input);
				p = strchr (cmd+2, ' ');
				if (p) {
					off = r_num_math (core->num, p+1);;
					*p = '\0';
				}
				cmd[0] = 's';
				// perform real seek if provided
				r_cmd_call (core->rcmd, cmd);
				free (cmd);
			}
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_seek_align (core, off, 0);
			break;
		case 'b':
			if (off == 0)
				off = core->offset;
			r_io_sundo_push (core->io, core->offset, r_print_get_cursor (core->print));
			r_core_anal_bb_seek (core, off);
			break;
		case 'f': // "sf"
			if (strlen(input) > 2 && input[1]==' ') {
				RAnalFunction *fcn = r_anal_fcn_find_name (core->anal, input+2);
				if (fcn) {
					r_core_seek (core, fcn->addr, 1);
				}
				break;
			}
			RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
			if (fcn) {
				r_core_seek (core, fcn->addr + r_anal_fcn_size (fcn), 1);
			}
			break;
		case 'o': // "so"
			{
			RAnalOp op;
			int val=0, ret, i, n = r_num_math (core->num, input+1);
			if (n==0) n = 1;
			if (n<0) {
				int instr_len;
				ut64 addr = core->offset;
				int numinstr = n * -1;
				if (r_core_prevop_addr (core, core->offset, numinstr, &addr)) {
					ret = core->offset - addr;
				} else {
					ret = r_core_asm_bwdis_len (core, &instr_len, &addr, numinstr);
				}
				r_core_seek (core, addr, true);
				val += ret;
			} else {
				for (val=i=0; i<n; i++) {
					ret = r_anal_op (core->anal, &op,
							core->offset, core->block, core->blocksize);
					if (ret<1)
						ret = 1;
					r_core_seek_delta (core, ret);
					val += ret;
				}
			}
			core->num->value = val;
			}
			break;
		case 'g': // "sg"
			{
			RIOSection *s = r_io_section_vget (core->io, core->offset);
			if (s) r_core_seek (core, s->vaddr, 1);
			else r_core_seek (core, 0, 1);
			}
			break;
		case 'G': // "sG"
			{
			if (!core->file) break;
			RIOSection *s = r_io_section_vget (core->io, core->offset);
			// XXX: this +2 is a hack. must fix gap between sections
			if (s) r_core_seek (core, s->vaddr+s->size+2, 1);
			else r_core_seek (core, r_io_desc_size (core->io, core->file->desc), 1);
			}
			break;
		case 'l': // "sl"
			{
			int sl_arg = r_num_math (core->num, input+1);
			const char *help_msg[] = {
				"Usage:", "sl+ or sl- or slc", "",
				"sl", " [line]", "Seek to absolute line",
				"sl", "[+-][line]", "Seek to relative line",
				"slc", "", "Clear line cache",
				"sll", "", "Show total number of lines",
				NULL };
			switch (input[1]) {
			case 0:
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__get_current_line (core);
				break;
			case ' ':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__seek_line_absolute (core, sl_arg);
				break;
			case '+':
			case '-':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				__seek_line_relative (core, sl_arg);
				break;
			case 'c':
				__clean_lines_cache (core);
				break;
			case 'l':
				if (!core->print->lines_cache) {
					__init_seek_line (core);
				}
				eprintf ("%d lines\n", core->print->lines_cache_sz-1);
				break;
			case '?':
				r_core_cmd_help (core, help_msg);
				break;
			}
			}
			break;
		case ':':
			printPadded (core, atoi (input + 1));
			break;
		case '?': {
			const char * help_message[] = {
			"Usage: s", "", " # Seek commands",
			"s", "", "Print current address",
			"s:", "pad", "Print current address with N padded zeros (defaults to 8)",
			"s", " addr", "Seek to address",
			"s-", "", "Undo seek",
			"s-", " n", "Seek n bytes backward",
			"s--", "", "Seek blocksize bytes backward",
			"s+", "", "Redo seek",
			"s+", " n", "Seek n bytes forward",
			"s++", "", "Seek blocksize bytes forward",
			"s[j*=]", "", "List undo seek history (JSON, =list, *r2)",
			"s/", " DATA", "Search for next occurrence of 'DATA'",
			"s/x", " 9091", "Search for next occurrence of \\x90\\x91",
			"s.", "hexoff", "Seek honoring a base from core->offset",
			"sa", " [[+-]a] [asz]", "Seek asz (or bsize) aligned to addr",
			"sb", "", "Seek aligned to bb start",
			"sC", "[?] string", "Seek to comment matching given string",
			"sf", "", "Seek to next function (f->addr+f->size)",
			"sf", " function", "Seek to address of specified function",
			"sg/sG", "", "Seek begin (sg) or end (sG) of section or file",
			"sl", "[?] [+-]line", "Seek to line",
			"sn/sp", "", "Seek next/prev scr.nkey",
			"so", " [N]", "Seek to N next opcode(s)",
			"sr", " pc", "Seek to register",
			//"sp [page]  seek page N (page = block)",
			NULL
			};
			r_core_cmd_help(core, help_message);
		}
			break;
		}
	} else r_cons_printf ("0x%"PFMT64x"\n", core->offset);
	return 0;
}
コード例 #15
0
ファイル: cmd_meta.c プロジェクト: Lukas-Dresel/radare2
void r_comment_vars(RCore *core, const char *input) {
	//TODO enable base64 and make it the default for C*
	RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
	int idx;
	char *oname = NULL, *name = NULL;
	char *oldcomment = NULL;
	char *heap_comment = NULL;
	RAnalVar *var;

	if (input[1] == '?' || (input[0] != 'b' && input[0] != 'r' && input[0] != 's') ) {
		r_comment_var_help (core, input[0]);
		return;
	}
	if (!fcn) {
		eprintf ("Cant find function here\n");
		return;
	}
	oname = name = strdup (input + 2);
	while (*name == ' ') {
		name++;
	}
	switch (input[1]) {
	case '*':
	case '\0': {
		RList *var_list;
		RListIter *iter;
		var_list = r_anal_var_list (core->anal, fcn, input[0]);
		r_list_foreach (var_list, iter, var) {
			oldcomment = r_meta_get_var_comment (core->anal, input[0], var->delta, fcn->addr);
			if (!oldcomment) {
				continue;
			}
			if (!input[1]) {
				r_cons_printf ("%s : %s\n", var->name, oldcomment);
			} else {
				r_cons_printf ("\"Cv%c %s base64:%s @ 0x%08"PFMT64x"\"\n", input[0], var->name,
					sdb_encode ((const ut8 *) oldcomment, strlen(oldcomment)), fcn->addr);
			}
		}
		}
		break;
	case ' ': {
		// TODO check that idx exist
		char *comment = strstr (name, " ");
		if (comment) { // new comment given
			if (*comment) {
				*comment++ = 0;
			}
			if (!strncmp (comment, "base64:", 7)) {
				heap_comment = (char *)sdb_decode (comment + 7, NULL);
				comment = heap_comment;
			}
		}
		var = r_anal_var_get_byname (core->anal, fcn, name);
		if (var) {
			idx = var->delta;
		} else if (!strncmp (name, "0x", 2))  {
			idx = (int) r_num_get (NULL, name);
		} else if (!strncmp (name, "-0x", 3)) {
			idx = -(int) r_num_get (NULL, name+1);
		} else {
			eprintf ("cant find variable named `%s`\n",name);
			free (heap_comment);
			break;
		}
		r_anal_var_free (var);
		if (!r_anal_var_get (core->anal, fcn->addr, input[0], 1, idx)) {
			eprintf ("cant find variable at given offset\n");
		} else {
			oldcomment = r_meta_get_var_comment (core->anal, input[0], idx, fcn->addr);
			if (oldcomment) {
				if (comment && *comment) {
					char *text = r_str_newf ("%s\n%s", oldcomment, comment);
					r_meta_set_var_comment (core->anal, input[0], idx, fcn->addr, text);
					free (text);
				} else {
					r_cons_println (oldcomment);
				}
			} else {
				r_meta_set_var_comment (core->anal, input[0], idx, fcn->addr, comment);
			}
		}
		free (heap_comment);
		}
		break;
	case '-':
		var = r_anal_var_get_byname (core->anal,fcn, name);
		if (var) {
			idx = var->delta;
		} else if (!strncmp (name, "0x", 2)) {
			idx = (int) r_num_get (NULL, name);
		} else if (!strncmp (name, "-0x", 3)) {
			idx = -(int) r_num_get (NULL, name+1);
		 }else {
			eprintf ("cant find variable named `%s`\n",name);
			break;
		}
		r_anal_var_free (var);
		//XXX TODO here we leak a var
		if (!r_anal_var_get (core->anal, fcn->addr, input[0],1,idx)) {
			eprintf ("cant find variable at given offset\n");
			break;
		}
		r_meta_var_comment_del (core->anal, input[0], idx, fcn->addr);
		break;
	case '!': {
		char *comment;
		var = r_anal_var_get_byname (core->anal,fcn, name);
		if (!var) {
			eprintf ("cant find variable named `%s`\n",name);
			break;
		}
		oldcomment = r_meta_get_var_comment (core->anal, input[0], var->delta, fcn->addr);
		comment = r_core_editor (core, NULL, oldcomment);
		if (comment) {
			r_meta_var_comment_del (core->anal, input[0], var->delta, fcn->addr);
			r_meta_set_var_comment (core->anal, input[0], var->delta, fcn->addr, comment);
			free (comment);
		}
		r_anal_var_free (var);
		}
		break;
	}