radare2/libr/core/cconfig.c

2336 lines
82 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2009-2017 - pancake */
#include <r_core.h>
#define SETI(x,y,z) r_config_node_desc(r_config_set_i(cfg,x,y), z);
#define SETICB(w,x,y,z) r_config_node_desc(r_config_set_i_cb(cfg,w,x,y), z);
#define SETPREF(x,y,z) r_config_node_desc(r_config_set(cfg,x,y), z);
#define SETCB(w,x,y,z) r_config_node_desc(r_config_set_cb(cfg,w,x,y), z);
/* TODO: use loop here */
2016-09-22 20:48:26 +05:30
/*------------------------------------------------------------------------------------------*/
static int compareName(const RAnalFunction *a, const RAnalFunction *b) {
return a && b && a->name && b->name && strcmp (a->name, b->name);
2016-09-22 20:48:26 +05:30
}
static int compareNameLen(const RAnalFunction *a, const RAnalFunction *b) {
return a && b && a->name && b->name && strlen (a->name) > strlen (b->name);
}
static int compareAddress(const RAnalFunction *a, const RAnalFunction *b) {
return a && b && a->addr && b->addr && a->addr > b->addr;
}
static int compareType(const RAnalFunction *a, const RAnalFunction *b) {
return a && b && a->diff->type && b->diff->type && a->diff->type > b->diff->type;
}
static int compareSize(const RAnalFunction *a, const RAnalFunction *b) {
// return a && b && a->_size < b->_size;
return a && b && r_anal_fcn_realsize (a) > r_anal_fcn_realsize (b);
}
static int compareDist(const RAnalFunction *a, const RAnalFunction *b) {
return a && b && a->diff->dist && b->diff->dist && a->diff->dist > b->diff->dist;
}
static int cb_diff_sort(void *_core, void *_node) {
RConfigNode *node = _node;
const char *column = node->value;
RCore *core = _core;
if (column && strcmp (column, "?")) {
if (!strcmp (column, "name")) {
core->anal->columnSort = (RListComparator)compareName;
} else if (!strcmp (column, "namelen")) {
core->anal->columnSort = (RListComparator)compareNameLen;
} else if (!strcmp (column, "addr")) {
core->anal->columnSort = (RListComparator)compareAddress;
} else if (!strcmp (column, "type")) {
core->anal->columnSort = (RListComparator)compareType;
} else if (!strcmp (column, "size")) {
core->anal->columnSort = (RListComparator)compareSize;
} else if (!strcmp (column, "dist")) {
core->anal->columnSort = (RListComparator)compareDist;
} else {
goto fail;
}
return true;
}
fail:
eprintf ("e diff.sort = [name, namelen, addr, type, size, dist]\n");
return false;
}
2016-09-22 20:48:26 +05:30
static const char *has_esil(RCore *core, const char *name) {
RListIter *iter;
RAnalPlugin *h;
RAnal *a = core->anal;
r_list_foreach (a->plugins, iter, h) {
if (!strcmp (name, h->name)) {
2016-07-03 20:05:01 +02:00
return h->esil? "Ae": "A_";
}
}
return "__";
}
// copypasta from binr/rasm2/rasm2.c
static void rasm2_list(RCore *core, const char *arch, int fmt) {
int i;
const char *feat2, *feat;
RAsm *a = core->assembler;
char bits[32];
RAsmPlugin *h;
RListIter *iter;
if (fmt == 'j') {
r_cons_print ("{");
}
r_list_foreach (a->plugins, iter, h) {
if (arch && *arch) {
if (h->cpus && !strcmp (arch, h->name)) {
char *c = strdup (h->cpus);
int n = r_str_split (c, ',');
for (i = 0; i < n; i++) {
r_cons_println (r_str_word_get0 (c, i));
}
free (c);
break;
}
} else {
bits[0] = 0;
/* The underscore makes it easier to distinguish the
* columns */
2014-07-02 23:18:50 +02:00
if (h->bits&8) strcat (bits, "_8");
if (h->bits&16) strcat (bits, "_16");
if (h->bits&32) strcat (bits, "_32");
if (h->bits&64) strcat (bits, "_64");
if (!*bits) strcat (bits, "_0");
feat = "__";
if (h->assemble && h->disassemble) feat = "ad";
if (h->assemble && !h->disassemble) feat = "a_";
if (!h->assemble && h->disassemble) feat = "_d";
feat2 = has_esil (core, h->name);
if (fmt == 'q') {
r_cons_println (h->name);
} else if (fmt == 'j') {
const char *str_bits = "32, 64";
const char *license = "GPL";
r_cons_printf ("\"%s\":{\"bits\":[%s],\"license\":\"%s\",\"description\":\"%s\",\"features\":\"%s\"}%s",
h->name, str_bits, license, h->desc, feat, iter->n? ",": "");
} else {
r_cons_printf ("%s%s %-9s %-11s %-7s %s\n",
feat, feat2, bits, h->name,
h->license?h->license:"unknown", h->desc);
}
}
}
if (fmt == 'j') {
r_cons_print ("}\n");
}
}
static inline void __setsegoff(RConfig *cfg, const char *asmarch, int asmbits) {
int autoseg = (!strncmp (asmarch, "x86", 3) && asmbits == 16);
r_config_set (cfg, "asm.segoff", r_str_bool (autoseg));
}
static int cb_debug_hitinfo(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->hitinfo = node->i_value;
return true;
}
static int cb_analeobjmp(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.eobjmp = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_analafterjmp(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.afterjmp = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_analsleep(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->sleep = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_analmaxrefs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->maxreflines = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2014-09-14 11:52:30 +02:00
static int cb_analnopskip (void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.nopskip = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2014-09-14 11:52:30 +02:00
}
static int cb_analhpskip (void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.hpskip = node->i_value;
return true;
}
static int cb_analbbsplit (void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.bbsplit = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2016-07-03 20:05:01 +02:00
/* obey section permissions */
static int cb_analnoncode(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
2016-07-03 20:05:01 +02:00
core->anal->opt.noncode = !!node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_analarch(void *user, void *data) {
2013-11-05 02:58:00 +01:00
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_anal_list (core->anal);
2015-09-14 12:35:38 +02:00
return false;
2013-11-05 02:58:00 +01:00
}
2016-07-03 20:05:01 +02:00
if (*node->value) {
if (r_anal_use (core->anal, node->value)) {
return true;
}
const char *aa = r_config_get (core->config, "asm.arch");
if (!aa || strcmp (aa, node->value)) {
eprintf ("anal.arch: cannot find '%s'\n", node->value);
}
}
return false;
2013-11-05 02:58:00 +01:00
}
static int cb_analcpu(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
r_anal_set_cpu (core->anal, node->value);
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_analsplit(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->split = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
2015-02-23 15:39:54 +01:00
static int cb_analrecont(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.recont = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2015-02-23 15:39:54 +01:00
}
static int cb_asmsecsub(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
core->print->flags |= R_PRINT_FLAGS_SECSUB;
} else {
core->print->flags &= (~R_PRINT_FLAGS_SECSUB);
}
r_print_set_flags (core->print, core->print->flags);
return true;
}
static int cb_asmassembler(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
r_asm_use_assembler (core->assembler, node->value);
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_asmarch(void *user, void *data) {
char asmparser[32];
2013-11-05 02:58:00 +01:00
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2016-12-19 17:10:52 +01:00
const char *asmos = NULL;
2015-08-31 12:46:29 +02:00
int bits = R_SYS_BITS;
2016-12-04 19:54:01 +01:00
if (!*node->value || !core || !core->assembler) {
return false;
}
2016-12-19 17:10:52 +01:00
asmos = r_config_get (core->config, "asm.os");
2016-12-04 19:54:01 +01:00
if (core && core->anal && core->anal->bits) {
2015-08-31 13:54:24 +02:00
bits = core->anal->bits;
2015-08-31 12:46:29 +02:00
}
if (*node->value == '?') {
rasm2_list (core, NULL, node->value[1]);
2015-09-14 12:35:38 +02:00
return false;
}
2015-08-31 13:54:24 +02:00
r_egg_setup (core->egg, node->value, bits, 0, R_SYS_OS);
if (!r_asm_use (core->assembler, node->value)) {
eprintf ("asm.arch: cannot find (%s)\n", node->value);
return false;
}
2017-01-25 23:20:20 +01:00
//we should strdup here otherwise will crash if any r_config_set
//free the old value
char *asm_cpu = strdup (r_config_get (core->config, "asm.cpu"));
2016-11-16 01:25:26 +01:00
if (core->assembler->cur) {
const char *newAsmCPU = core->assembler->cur->cpus;
if (newAsmCPU) {
if (*newAsmCPU) {
char *nac = strdup (newAsmCPU);
char *comma = strchr (nac, ',');
if (comma) {
*comma = 0;
r_config_set (core->config, "asm.cpu", nac);
}
2016-12-04 19:54:01 +01:00
free (nac);
2016-11-16 01:25:26 +01:00
} else {
r_config_set (core->config, "asm.cpu", "");
}
}
2015-08-31 13:54:24 +02:00
bits = core->assembler->cur->bits;
if (8 & bits) {
bits = 8;
} else if (16 & bits) {
bits = 16;
} else if (32 & bits) {
bits = 32;
} else {
bits = 64;
}
2015-08-31 13:54:24 +02:00
}
snprintf (asmparser, sizeof (asmparser), "%s.pseudo", node->value);
r_config_set (core->config, "asm.parser", asmparser);
2016-12-04 19:54:01 +01:00
if (core->assembler->cur && core->anal &&
!(core->assembler->cur->bits & core->anal->bits)) {
r_config_set_i (core->config, "asm.bits", bits);
2013-11-05 02:58:00 +01:00
}
2015-08-31 12:46:29 +02:00
2015-10-22 03:11:03 +02:00
//r_debug_set_arch (core->dbg, r_sys_arch_id (node->value), bits);
r_debug_set_arch (core->dbg, node->value, bits);
2013-12-07 14:25:15 +01:00
if (!r_config_set (core->config, "anal.arch", node->value)) {
2013-11-05 02:58:00 +01:00
char *p, *s = strdup (node->value);
2015-11-05 16:45:45 +01:00
if (s) {
p = strchr (s, '.');
if (p) {
*p = 0;
}
2015-11-05 16:45:45 +01:00
if (!r_config_set (core->config, "anal.arch", s)) {
/* fall back to the anal.null plugin */
r_config_set (core->config, "anal.arch", "null");
}
free (s);
}
2013-11-05 02:58:00 +01:00
}
2015-11-02 18:57:01 +01:00
// set pcalign
{
int v = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_ALIGN);
if (v != -1) {
r_config_set_i (core->config, "asm.pcalign", v);
} else {
r_config_set_i (core->config, "asm.pcalign", 0);
}
2015-11-02 18:57:01 +01:00
}
2016-12-04 19:54:01 +01:00
if (core->anal) {
if (!r_syscall_setup (core->anal->syscall, node->value, asmos, core->anal->bits)) {
//eprintf ("asm.arch: Cannot setup syscall '%s/%s' from '%s'\n",
// node->value, asmos, R2_LIBDIR"/radare2/"R2_VERSION"/syscall");
}
2013-11-05 02:58:00 +01:00
}
//if (!strcmp (node->value, "bf"))
// r_config_set (core->config, "dbg.backend", "bf");
__setsegoff (core->config, node->value, core->assembler->bits);
2016-05-10 21:12:50 +01:00
// set a default endianness
int bigbin = r_bin_is_big_endian (core->bin);
if (bigbin == -1 /* error: no endianness detected in binary */) {
// try to set RAsm to LE
r_asm_set_big_endian (core->assembler, false);
// set endian of display to LE
core->print->big_endian = false;
} else {
// try to set endian of RAsm to match binary
r_asm_set_big_endian (core->assembler, bigbin);
// set endian of display to match binary
core->print->big_endian = bigbin;
}
2017-01-24 13:57:17 +01:00
r_asm_set_cpu (core->assembler, asm_cpu);
2017-01-25 23:20:20 +01:00
free (asm_cpu);
/* reload types and cc info */
// changing asm.arch changes anal.arch
// changing anal.arch sets types db
// so ressetting is redundant and may lead to bugs
// 1 case this is usefull is when sdb_types is null
if (!core->anal->sdb_types) {
r_core_anal_type_init (core);
}
r_core_anal_cc_init (core);
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_dbgbpsize(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->dbg->bpsize = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2015-08-22 20:19:33 +08:00
static int cb_dbgbtdepth(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->dbg->btdepth = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2015-08-22 20:19:33 +08:00
}
2013-11-05 02:58:00 +01:00
static int cb_asmbits(void *user, void *data) {
const char *asmos, *asmarch;
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2016-04-08 13:36:15 +02:00
int ret = 0, bits;
2014-05-22 11:22:48 +02:00
if (!core) {
eprintf ("user can't be NULL\n");
2015-09-14 12:35:38 +02:00
return false;
2014-05-22 11:22:48 +02:00
}
2016-04-08 13:36:15 +02:00
bits = node->i_value;
if (bits > 0) {
ret = r_asm_set_bits (core->assembler, bits);
if (!ret) {
2016-04-08 13:36:15 +02:00
RAsmPlugin *h = core->assembler->cur;
if (h) {
eprintf ("Cannot set bits %d to '%s'\n", bits, h->name);
} else {
eprintf ("e asm.bits: Cannot set value, no plugins defined yet\n");
ret = true;
}
2013-11-05 02:58:00 +01:00
}
if (!r_anal_set_bits (core->anal, bits)) {
2016-04-08 13:36:15 +02:00
eprintf ("asm.arch: Cannot setup '%d' bits analysis engine\n", bits);
}
core->print->bits = bits;
2013-11-05 02:58:00 +01:00
}
if (core->dbg && core->anal && core->anal->cur) {
2016-04-08 13:36:15 +02:00
bool load_from_debug = false;
r_debug_set_arch (core->dbg, core->anal->cur->arch, bits);
if (r_config_get_i (core->config, "cfg.debug")) {
2016-04-08 13:36:15 +02:00
load_from_debug = true;
} else {
2016-04-08 13:36:15 +02:00
(void)r_anal_set_reg_profile (core->anal);
}
if (load_from_debug) {
if (core->dbg->h && core->dbg->h->reg_profile) {
#if __WINDOWS__
#if !defined(__MINGW64__)
core->dbg->bits = R_SYS_BITS_32;
#else
core->dbg->bits = R_SYS_BITS_64;
#endif
#endif
char *rp = core->dbg->h->reg_profile (core->dbg);
r_reg_set_profile_string (core->dbg->reg, rp);
r_reg_set_profile_string (core->anal->reg, rp);
free (rp);
}
}
}
2013-11-05 02:58:00 +01:00
asmos = r_config_get (core->config, "asm.os");
asmarch = r_config_get (core->config, "asm.arch");
2014-06-25 03:07:54 +02:00
if (core->anal) {
2016-04-08 13:36:15 +02:00
if (!r_syscall_setup (core->anal->syscall, asmarch, asmos, bits)) {
2013-11-05 02:58:00 +01:00
//eprintf ("asm.arch: Cannot setup syscall '%s/%s' from '%s'\n",
// node->value, asmos, R2_LIBDIR"/radare2/"R2_VERSION"/syscall");
}
2014-06-25 03:07:54 +02:00
__setsegoff (core->config, asmarch, core->anal->bits);
2015-06-27 20:31:37 +03:00
if (core->dbg) {
r_bp_use (core->dbg->bp, asmarch, core->anal->bits);
}
2014-06-25 03:07:54 +02:00
}
2016-07-03 20:05:01 +02:00
/* set pcalign */
{
int v = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_ALIGN);
if (v != -1) {
r_config_set_i (core->config, "asm.pcalign", v);
} else {
r_config_set_i (core->config, "asm.pcalign", 0);
}
}
2013-11-05 02:58:00 +01:00
return ret;
}
static int cb_asmfeatures(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2015-02-18 13:04:59 +01:00
if (*node->value == '?') {
if (core && core->assembler && core->assembler->cur) {
if (core->assembler->cur->features) {
char *feat = strdup (core->assembler->cur->features);
r_str_replace_char (feat, ',','\n');
r_cons_println (feat);
free (feat);
}
}
return 0;
}
free (core->assembler->features);
2015-02-18 13:04:59 +01:00
core->assembler->features = NULL;
2016-07-03 20:05:01 +02:00
if (node->value[0]) {
core->assembler->features = strdup (node->value);
2016-07-03 20:05:01 +02:00
}
return 1;
}
2013-11-05 02:58:00 +01:00
static int cb_asmcpu(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (*node->value == '?') {
rasm2_list (core, r_config_get (core->config, "asm.arch"), node->value[1]);
return 0;
}
2013-11-05 02:58:00 +01:00
r_asm_set_cpu (core->assembler, node->value);
r_config_set (core->config, "anal.cpu", node->value);
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_asmlineswidth(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->anal->lineswidth = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_emustr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
r_config_set (core->config, "asm.emu", "true");
}
return true;
}
static int cb_emuskip(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("Concatenation of meta types encoded as characters:\n" \
"'d': data\n'c': code\n's': string\n'f': format\n'm': magic\n" \
"'h': hide\n'C': comment\n'r': run\n" \
"(default is 'ds' to skip data and strings)\n");
return false;
}
return true;
}
static int cb_asm_invhex(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->assembler->invhex = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_asm_pcalign(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
int align = node->i_value;
if (align < 0) {
align = 0;
}
core->assembler->pcalign = align;
core->anal->pcalign = align;
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_asmos(void *user, void *data) {
RCore *core = (RCore*) user;
int asmbits = r_config_get_i (core->config, "asm.bits");
2014-11-04 11:47:42 +01:00
RConfigNode *asmarch, *node = (RConfigNode*) data;
2015-09-01 03:13:16 +02:00
if (*node->value == '?') {
r_cons_printf ("ios\ndos\ndarwin\nlinux\nfreebsd\nopenbsd\nnetbsd\nwindows\n");
2014-11-04 11:47:42 +01:00
return 0;
}
2015-09-01 03:13:16 +02:00
if (!node->value[0]) {
free (node->value);
node->value = strdup (R_SYS_OS);
}
2014-11-04 11:47:42 +01:00
asmarch = r_config_node_get (core->config, "asm.arch");
2013-11-05 02:58:00 +01:00
if (asmarch) {
r_syscall_setup (core->anal->syscall, asmarch->value,
node->value, core->anal->bits);
__setsegoff (core->config, asmarch->value, asmbits);
}
r_anal_set_os (core->anal, node->value);
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_asmparser(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
return r_parse_use (core->parser, node->value);
}
static int cb_binfilter(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->bin->filter = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
/* BinDemangleCmd */
static int cb_bdc(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->bin->demanglercmd = node->i_value;
return true;
}
static int cb_strpurge(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->bin->strpurge = node->i_value;
return true;
}
2015-12-17 20:18:50 +01:00
static int cb_midflags (void *user, void *data) {
RConfigNode *node = (RConfigNode *)data;
if (node->value[0] == '?') {
eprintf ("Valid values for asm.midflags:\n");
2016-07-03 20:05:01 +02:00
eprintf ("0 do not show middle flags\n");
eprintf ("1 print the middfle flag without realign instruction\n");
2016-11-02 12:10:50 +01:00
eprintf ("2 realign the instruction at the middle flag\n");
eprintf ("3 realign the instruction at the middle flag only if it's a sym.\n");
2015-12-17 20:18:50 +01:00
return false;
}
return true;
}
static int cb_strfilter(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (node->value[0] == '?') {
eprintf ("Valid values for bin.strfilter:\n");
eprintf ("a only alphanumeric printable\n");
eprintf ("8 only strings with utf8 chars\n");
eprintf ("p file/directory paths\n");
eprintf ("e email-like addresses\n");
eprintf ("u urls\n");
eprintf ("i IPv4 address-like strings\n");
eprintf ("U only uppercase strings\n");
eprintf ("f format-strings\n");
return false;
} else {
core->bin->strfilter = node->value[0];
}
return true;
}
static int cb_binforce(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
r_bin_force_plugin (core->bin, node->value);
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_asmsyntax(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("att\nintel\nmasm\njz\nregnum\n");
2015-09-14 12:35:38 +02:00
return false;
} else {
int syntax = r_asm_syntax_from_string (node->value);
if (syntax == -1) {
return false;
}
r_asm_set_syntax (core->assembler, syntax);
}
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_bigendian(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
// Try to set endian based on preference, restrict by RAsmPlugin
bool isbig = r_asm_set_big_endian (core->assembler, node->i_value);
// Set anal endianness the same as asm
r_anal_set_big_endian (core->anal, isbig);
2016-09-06 12:02:38 +02:00
// the big endian should also be assigned to dbg->bp->endian
core->dbg->bp->endian = isbig;
// Set printing endian to user's choice
2013-11-05 02:58:00 +01:00
core->print->big_endian = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_cfgdatefmt(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
snprintf (core->print->datefmt, 32, "%s", node->value);
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_timezone(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->print->datezone = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_cfgdebug(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
2015-09-14 12:35:38 +02:00
if (!core) return false;
if (core->io) {
2013-11-05 02:58:00 +01:00
core->io->debug = node->i_value;
}
2013-11-05 02:58:00 +01:00
if (core->dbg && node->i_value) {
const char *dbgbackend = r_config_get (core->config, "dbg.backend");
2015-09-14 12:35:38 +02:00
core->bin->is_debugger = true;
2013-11-05 02:58:00 +01:00
r_debug_use (core->dbg, dbgbackend);
if (!strcmp (r_config_get (core->config, "cmd.prompt"), "")) {
r_config_set (core->config, "cmd.prompt", ".dr*");
}
2013-11-05 02:58:00 +01:00
if (!strcmp (dbgbackend, "bf"))
r_config_set (core->config, "asm.arch", "bf");
if (core->file) {
2015-11-24 23:28:50 +01:00
#if __WINDOWS__
r_debug_select (core->dbg, core->dbg->pid,
core->dbg->tid);
#else
r_debug_select (core->dbg, core->file->desc->fd,
core->file->desc->fd);
2015-11-24 23:28:50 +01:00
#endif
2013-11-05 02:58:00 +01:00
}
} else {
if (core->dbg) r_debug_use (core->dbg, NULL);
2015-09-14 12:35:38 +02:00
core->bin->is_debugger = false;
}
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_dirsrc(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
RCore *core = (RCore *)user;
free (core->bin->srcdir);
core->bin->srcdir = strdup (node->value);
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_cfgsanbox(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
int ret = r_sandbox_enable (node->i_value);
2016-07-03 20:05:01 +02:00
if (node->i_value != ret) {
eprintf ("Cannot disable sandbox\n");
2016-07-03 20:05:01 +02:00
}
2013-11-05 02:58:00 +01:00
return (!node->i_value && ret)? 0: 1;
}
static int cb_cmdrepeat(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->cmdrepeat = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
2014-01-08 23:44:05 +01:00
static int cb_scrnull(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->cons->null = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2014-01-08 23:44:05 +01:00
}
2013-11-05 02:58:00 +01:00
static int cb_color(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
if (node->i_value) {
core->print->flags |= R_PRINT_FLAGS_COLOR;
} else {
//c:core->print->flags ^= R_PRINT_FLAGS_COLOR;
core->print->flags &= (~R_PRINT_FLAGS_COLOR);
}
r_cons_singleton ()->use_color = node->i_value? 1: 0;
2013-11-05 02:58:00 +01:00
r_print_set_flags (core->print, core->print->flags);
2015-09-14 12:35:38 +02:00
return true;
}
2016-11-01 23:30:36 +01:00
static int cb_decoff(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
core->print->flags |= R_PRINT_FLAGS_ADDRDEC;
} else {
core->print->flags &= (~R_PRINT_FLAGS_ADDRDEC);
}
r_print_set_flags (core->print, core->print->flags);
return true;
}
2014-05-07 23:21:34 +02:00
static int cb_dbgbep(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("loader\nentry\nconstructor\nmain\n");
2015-09-14 12:35:38 +02:00
return false;
2014-05-07 23:21:34 +02:00
}
2015-09-14 12:35:38 +02:00
return true;
2014-05-07 23:21:34 +02:00
}
static int cb_dbg_btalgo(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("default\nfuzzy\nanal\n");
2015-09-14 12:35:38 +02:00
return false;
}
free (core->dbg->btalgo);
core->dbg->btalgo = strdup (node->value);
2015-09-14 12:35:38 +02:00
return true;
}
2015-10-13 02:18:14 +02:00
static int cb_dbg_libs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
free (core->dbg->glob_libs);
core->dbg->glob_libs = strdup (node->value);
return true;
}
static int cb_dbg_unlibs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
free (core->dbg->glob_unlibs);
core->dbg->glob_unlibs = strdup (node->value);
return true;
}
static int cb_dbg_forks(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->trace_forks = node->i_value;
if (core->io->debug) {
r_debug_attach (core->dbg, core->dbg->pid);
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_dbg_execs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->trace_execs = node->i_value;
if (core->io->debug) {
r_debug_attach (core->dbg, core->dbg->pid);
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_dbg_clone(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->trace_clone = node->i_value;
if (core->io->debug) {
r_debug_attach (core->dbg, core->dbg->pid);
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_dbg_follow_child(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->follow_child = node->i_value;
return true;
}
static int cb_dbg_aftersc(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->dbg->trace_aftersyscall = node->i_value;
if (core->io->debug) {
r_debug_attach (core->dbg, core->dbg->pid);
}
return true;
}
2014-08-11 16:07:17 +02:00
static int cb_runprofile(void *user, void *data) {
RCore *r = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
free ((void*)r->io->runprofile);
2016-07-03 20:05:01 +02:00
if (!node || !*(node->value)) {
r->io->runprofile = NULL;
} else {
r->io->runprofile = strdup (node->value);
}
2015-09-14 12:35:38 +02:00
return true;
}
2014-05-07 23:21:34 +02:00
2015-09-30 13:10:49 +02:00
static int cb_dbg_args(void *user, void *data) {
RCore *core = (RCore *)user;
RConfigNode *node = (RConfigNode*) data;
2016-07-03 20:05:01 +02:00
if (!node || !*(node->value)) {
core->io->args = NULL;
} else {
core->io->args = strdup (node->value);
}
2015-09-30 13:10:49 +02:00
return true;
}
static int cb_dbgstatus(void *user, void *data) {
RCore *r = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
if (r_config_get_i (r->config, "cfg.debug")) {
2016-07-03 20:05:01 +02:00
if (node->i_value) {
r_config_set (r->config, "cmd.prompt",
2015-10-31 01:57:52 +01:00
".dr*; drd; sr PC;pi 1;s-");
2016-07-03 20:05:01 +02:00
} else {
r_config_set (r->config, "cmd.prompt", ".dr*");
}
}
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_dbgbackend(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
2016-10-04 14:34:06 +02:00
if (!strcmp (node->value, "?")) {
r_debug_plugin_list (core->dbg, 'q');
return false;
}
2016-07-03 20:05:01 +02:00
if (!strcmp (node->value, "bf")) {
2013-11-05 02:58:00 +01:00
r_config_set (core->config, "asm.arch", "bf");
2016-07-03 20:05:01 +02:00
}
2013-11-05 02:58:00 +01:00
r_debug_use (core->dbg, node->value);
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_gotolimit(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode*) data;
if (r_sandbox_enable (0)) {
eprintf ("Cannot change gotolimit\n");
2015-09-14 12:35:38 +02:00
return false;
}
2016-07-03 20:05:01 +02:00
if (core->anal->esil) {
core->anal->esil_goto_limit = node->i_value;
2016-07-03 20:05:01 +02:00
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_esilverbose (void *user, void *data) {
2015-03-12 16:45:23 +01:00
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode*) data;
if (core->anal->esil) {
core->anal->esil->verbose = node->i_value;
}
2015-09-14 12:35:38 +02:00
return true;
2015-03-12 16:45:23 +01:00
}
static int cb_esilstackdepth (void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (node->i_value < 3) {
eprintf ("esil.stack.depth must be greater than 2\n");
node->i_value = 32;
}
return true;
}
2014-01-09 00:29:00 +01:00
static int cb_fixrows(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
2016-01-14 23:41:01 +01:00
r_cons_singleton ()->fix_rows = (int)node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2014-01-09 00:29:00 +01:00
static int cb_fixcolumns(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
2016-01-14 23:41:01 +01:00
r_cons_singleton ()->fix_columns = atoi (node->value);
2015-09-14 12:35:38 +02:00
return true;
2014-01-09 00:29:00 +01:00
}
static int cb_rows(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton ()->force_rows = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_hexcompact(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
core->print->flags |= R_PRINT_FLAGS_COMPACT;
} else {
core->print->flags &= (~R_PRINT_FLAGS_COMPACT);
}
return true;
}
static int cb_hexpairs(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->print->pairs = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_hexcomments(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
core->print->flags |= R_PRINT_FLAGS_COMMENT;
} else {
core->print->flags &= ~R_PRINT_FLAGS_COMMENT;
}
return true;
}
R_API bool r_core_esil_cmd(RAnalEsil *esil, const char *cmd, ut64 a1, ut64 a2) {
if (cmd && *cmd) {
RCore *core = esil->anal->user;
r_core_cmdf (core, "%s %"PFMT64d" %" PFMT64d, cmd, a1, a2);
2015-09-14 12:35:38 +02:00
return true;
}
2015-09-14 12:35:38 +02:00
return false;
}
static int cb_cmd_esil_intr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core && core->anal && core->anal->esil) {
core->anal->esil->cmd = r_core_esil_cmd;
core->anal->esil->cmd_intr = node->value;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_mdevrange(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core && core->anal && core->anal->esil) {
core->anal->esil->mdev_range = node->value;
}
return true;
}
static int cb_cmd_esil_mdev(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core && core->anal && core->anal->esil) {
core->anal->esil->cmd = r_core_esil_cmd;
core->anal->esil->cmd_mdev = node->value;
}
return true;
}
static int cb_cmd_esil_trap(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core && core->anal && core->anal->esil) {
core->anal->esil->cmd = r_core_esil_cmd;
core->anal->esil->cmd_trap = node->value;
}
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_fsview(void *user, void *data) {
int type = R_FS_VIEW_NORMAL;
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (*node->value == '?') {
eprintf ("Values: all|deleted|special\n");
2015-09-14 12:35:38 +02:00
return false;
}
2016-07-03 20:05:01 +02:00
if (!strcmp (node->value, "all")) {
type = R_FS_VIEW_ALL;
2016-07-03 20:05:01 +02:00
}
if (!strstr (node->value, "del")) {
type |= R_FS_VIEW_DELETED;
2016-07-03 20:05:01 +02:00
}
if (!strstr (node->value, "spe")) {
type |= R_FS_VIEW_SPECIAL;
2016-07-03 20:05:01 +02:00
}
r_fs_view (core->fs, type);
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_cmddepth(void *user, void *data) {
int c = R_MAX (((RConfigNode*)data)->i_value, 0);
((RCore *)user)->cmd_depth = c;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_hexcols(void *user, void *data) {
RCore *core = (RCore *)user;
2013-11-05 02:58:00 +01:00
int c = R_MIN (128, R_MAX (((RConfigNode*)data)->i_value, 0));
core->print->cols = c & ~1;
core->dbg->regcols = c/4;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_hexstride(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
((RCore *)user)->print->stride = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2015-02-03 00:46:44 +01:00
static int cb_search_kwidx(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->search->n_kws = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2015-02-03 00:46:44 +01:00
}
static int cb_ioenforce(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
int perm = node->i_value;
core->io->enforce_rwx = 0;
2016-07-03 20:05:01 +02:00
if (perm & 1) {
core->io->enforce_rwx |= R_IO_READ;
}
if (perm & 2) {
core->io->enforce_rwx |= R_IO_WRITE;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_iosectonly(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->sectonly = node->i_value? 1: 0;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_iobuffer(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
if (node->i_value) {
ut64 from, to;
from = r_config_get_i (core->config, "io.buffer.from");
to = r_config_get_i (core->config, "io.buffer.to");
if (from>=to) {
eprintf ("ERROR: io.buffer.from >= io.buffer.to"
" (0x%"PFMT64x" >= 0x%"PFMT64x")\n", from, to);
} else r_io_buffer_load (core->io, from, (int)(to-from));
2016-07-03 20:05:01 +02:00
} else {
r_io_buffer_close (core->io);
}
r_core_block_read (core);
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_iocache(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2015-12-08 17:56:35 +01:00
if ((int)node->i_value < 0) {
r_io_cache_reset (core->io, node->i_value);
}
2013-11-05 02:58:00 +01:00
r_io_cache_enable (core->io, node->i_value, node->i_value);
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_ioaslr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value != core->io->aslr) {
core->io->aslr = node->i_value;
}
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_iova(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
if (node->i_value != core->io->va) {
core->io->va = node->i_value;
2016-07-03 20:05:01 +02:00
/* ugly fix for r2 -d ... "r2 is going to die soon ..." */
if (r_io_desc_get (core->io, core->io->raised)) {
r_core_block_read (core);
2016-07-03 20:05:01 +02:00
}
/* reload symbol information */
if (r_list_length (r_bin_get_sections (core->bin)) > 0) {
2013-11-05 02:58:00 +01:00
r_core_cmd0 (core, ".ia*");
2016-07-03 20:05:01 +02:00
}
2013-11-05 02:58:00 +01:00
}
2015-09-14 12:35:38 +02:00
return true;
}
2016-11-04 01:30:35 +01:00
static int cb_iopava(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->pava = node->i_value;
return true;
}
2014-06-10 11:20:17 +02:00
static int cb_ioff(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->ff = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_io_oxff(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->Oxff = node->i_value;
return true;
}
2014-06-03 15:55:56 +02:00
static int cb_ioautofd(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->autofd = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2014-06-03 15:55:56 +02:00
}
2015-02-09 23:13:49 +01:00
static int cb_iovio(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->io->vio = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2015-02-09 23:13:49 +01:00
}
2013-11-05 02:58:00 +01:00
static int cb_pager(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
/* Let cons know we have a new pager. */
core->cons->pager = node->value;
2015-09-14 12:35:38 +02:00
return true;
}
2014-02-24 16:10:12 +01:00
static int cb_fps(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton ()->fps = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2014-02-24 16:10:12 +01:00
}
2013-11-05 02:58:00 +01:00
static int cb_rgbcolors(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
RCore *core = (RCore *) user;
if (node->i_value) {
r_cons_singleton()->truecolor =
(r_config_get_i (core->config, "scr.truecolor"))?2:1;
} else {
r_cons_singleton()->truecolor = 0;
}
2015-09-14 12:35:38 +02:00
return true;
}
2016-12-18 00:55:10 +01:00
static int cb_scrbreakword(void* user, void* data) {
2016-12-17 10:42:15 +01:00
RConfigNode *node = (RConfigNode*) data;
if (*node->value) {
r_cons_breakword (node->value);
} else {
r_cons_breakword (NULL);
}
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_scrcolumns(void* user, void* data) {
RConfigNode *node = (RConfigNode*) data;
RCore *core = (RCore*) user;
2013-11-05 02:58:00 +01:00
int n = atoi (node->value);
core->cons->force_columns = n;
2016-07-03 20:05:01 +02:00
core->dbg->regcols = n / 20;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_scrfgets(void* user, void* data) {
RCore *core = (RCore *) user;
2013-11-05 02:58:00 +01:00
RConfigNode *node = (RConfigNode*) data;
2016-07-03 20:05:01 +02:00
core->cons->user_fgets = node->i_value
? NULL : (void *)r_core_fgets;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_scrhtml(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
r_cons_singleton ()->is_html = node->i_value;
// TODO: control error and restore old value (return false?) show errormsg?
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_scrhighlight(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_highlight (node->value);
2015-09-14 12:35:38 +02:00
return true;
}
2015-11-01 05:10:49 +01:00
#if __WINDOWS__ && !__CYGWIN__
static int scr_ansicon(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->ansicon = node->i_value;
return true;
}
#endif
static int cb_screcho(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->echo = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_scrlinesleep(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->linesleep = node->i_value;
return true;
}
static int cb_scrpagesize(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->pagesize= node->i_value;
return true;
}
static int cb_scrflush(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->flush = node->i_value;
return true;
}
2015-09-23 12:46:22 +02:00
static int cb_exectrap(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
RCore *core = (RCore*) user;
if (core->anal && core->anal->esil) {
core->anal->esil->exectrap = node->i_value;
}
return true;
}
static int cb_iotrap(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
RCore *core = (RCore*) user;
if (core->anal && core->anal->esil) {
core->anal->esil->iotrap = node->i_value;
}
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_scrint(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
if (node->i_value && r_sandbox_enable (0)) {
2015-09-14 12:35:38 +02:00
return false;
2015-02-12 17:23:30 +01:00
}
2013-11-05 02:58:00 +01:00
r_cons_singleton()->is_interactive = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_scrnkey(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (!strcmp (node->value, "help") || *node->value == '?') {
r_cons_printf ("scr.nkey = fun, hit, flag\n");
2015-09-14 12:35:38 +02:00
return false;
}
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_scrprompt(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_line_singleton()->echo = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_scrrows(void* user, void* data) {
RConfigNode *node = (RConfigNode*) data;
int n = atoi (node->value);
((RCore *)user)->cons->force_rows = n;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_contiguous(void *user, void *data) {
RCore *core = (RCore *)user;
RConfigNode *node = (RConfigNode *) data;
core->search->contiguous = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_searchalign(void *user, void *data) {
RCore *core = (RCore *)user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
core->search->align = node->i_value;
core->print->addrmod = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_segoff(void *user, void *data) {
RCore *core = (RCore *) user;
2013-11-05 02:58:00 +01:00
RConfigNode *node = (RConfigNode *) data;
2016-11-01 23:30:36 +01:00
if (node->i_value) {
2013-11-05 02:58:00 +01:00
core->print->flags |= R_PRINT_FLAGS_SEGOFF;
2016-11-01 23:30:36 +01:00
} else {
core->print->flags &= (((ut32)-1) & (~R_PRINT_FLAGS_SEGOFF));
}
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_stopthreads(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
core->dbg->stop_all_threads = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_swstep(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
core->dbg->swstep = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_consbreak(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->dbg->consbreak = node->i_value;
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_teefile(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
r_cons_singleton()->teefile = node->value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_anal_trace(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core->anal) {
if (node->i_value && !core->anal->esil) {
r_core_cmd0 (core, "aei");
}
core->anal->trace = node->i_value;
}
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_trace(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->dbg->trace->enabled = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_tracetag(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2013-11-05 02:58:00 +01:00
core->dbg->trace->tag = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
2013-11-05 02:58:00 +01:00
static int cb_truecolor(void *user, void *data) {
RConfigNode *node = (RConfigNode *) data;
if (r_cons_singleton()->truecolor)
r_cons_singleton()->truecolor = (node->i_value)? 2: 1;
2015-09-14 12:35:38 +02:00
return true;
}
2013-11-05 02:58:00 +01:00
static int cb_utf8(void *user, void *data) {
2013-07-19 00:20:23 +04:00
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2016-10-21 01:24:40 +02:00
core->cons->use_utf8 = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
2013-07-19 00:20:23 +04:00
}
2013-11-05 02:58:00 +01:00
static int cb_zoombyte(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
switch (*node->value) {
case 'p': case 'f': case 's': case '0':
case 'F': case 'e': case 'h':
core->print->zoom->mode = *node->value;
break;
default:
eprintf ("Invalid zoom.byte value. See pz? for help\n");
2015-09-14 12:35:38 +02:00
return false;
2013-11-05 02:58:00 +01:00
}
2015-09-14 12:35:38 +02:00
return true;
2013-11-05 02:58:00 +01:00
}
static int cb_binverbose(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->bin->verbose = node->i_value;
return true;
}
static int cb_rawstr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->bin->rawstr = node->i_value;
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_debase64(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
core->bin->debase64 = node->i_value;
return true;
}
2016-10-16 02:57:08 +02:00
static int cb_binstrings(void *user, void *data) {
const ut32 req = R_BIN_REQ_STRINGS;
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (node->i_value) {
core->bin->filter_rules |= req;
} else {
core->bin->filter_rules &= ~req;
}
return true;
}
2015-10-22 20:26:24 +02:00
static int cb_binprefix(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
2016-10-29 13:06:11 +02:00
if (!core || !core->bin) {
2016-10-26 23:22:04 +02:00
return false;
}
2015-10-22 20:26:24 +02:00
if (node->value && *node->value) {
if (!strcmp (node->value, "auto")) {
2016-10-29 13:06:11 +02:00
if (!core->bin->file) {
2015-10-22 20:26:24 +02:00
return false;
}
2016-10-29 13:06:11 +02:00
char *name = (char *)r_file_basename (core->bin->file);
if (name) {
r_name_filter (name, strlen (name));
r_str_filter (name, strlen (name));
core->bin->prefix = strdup (name);
free (name);
}
2015-10-22 20:26:24 +02:00
} else {
core->bin->prefix = node->value;
}
}
return true;
}
static int cb_binmaxstrbuf(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core->bin) {
int v = node->i_value;
ut64 old_v = core->bin->maxstrbuf;
2015-10-22 20:26:24 +02:00
if (v < 1) v = 4; // HACK
core->bin->maxstrbuf = v;
2016-07-03 20:05:01 +02:00
if (v>old_v) {
r_core_bin_refresh_strings (core);
2016-07-03 20:05:01 +02:00
}
return true;
}
return true;
}
static int cb_binmaxstr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core->bin) {
int v = node->i_value;
if (v<1) v = 4; // HACK
core->bin->maxstrlen = v;
// TODO: Do not refresh if nothing changed (minstrlen ?)
r_core_bin_refresh_strings (core);
2015-09-14 12:35:38 +02:00
return true;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_binminstr(void *user, void *data) {
RCore *core = (RCore *) user;
RConfigNode *node = (RConfigNode *) data;
if (core->bin) {
int v = node->i_value;
if (v<1) v = 4; // HACK
core->bin->minstrlen = v;
// TODO: Do not refresh if nothing changed (minstrlen ?)
r_core_bin_refresh_strings (core);
2015-09-14 12:35:38 +02:00
return true;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_searchin(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
2014-10-15 12:08:34 +02:00
r_cons_printf ("raw\nblock\nfile\nio.maps\nio.maprange\nio.section\n" \
"io.sections\nio.sections.write\nio.sections.exec\n" \
"dbg.stack\ndbg.heap\ndbg.map\ndbg.maps\n"\
"dbg.maps.exec\ndbg.maps.write\nanal.fcn\nanal.bb\n");
2015-09-14 12:35:38 +02:00
return false;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int cb_fileloadmethod(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("fail\noverwrite\nappend\n");
2015-09-14 12:35:38 +02:00
return false;
}
2015-09-14 12:35:38 +02:00
return true;
}
static int __dbg_swstep_getter(void *user, RConfigNode *node) {
RCore *core = (RCore*)user;
node->i_value = core->dbg->swstep;
2016-07-03 20:05:01 +02:00
return true;
}
static int cb_anal_gp(RCore *core, RConfigNode *node) {
core->anal->gp = node->i_value;
2016-07-03 20:05:01 +02:00
return true;
}
2014-11-03 04:05:19 +01:00
static int cb_anal_from(RCore *core, RConfigNode *node) {
if (r_config_get_i (core->config, "anal.limits")) {
r_anal_set_limits (core->anal,
2014-11-03 04:05:19 +01:00
r_config_get_i (core->config, "anal.from"),
r_config_get_i (core->config, "anal.to"));
}
2016-07-03 20:05:01 +02:00
return true;
2014-11-03 04:05:19 +01:00
}
static int cb_anal_limits(void *user, RConfigNode *node) {
RCore *core = (RCore*)user;
if (node->i_value) {
r_anal_set_limits (core->anal,
2014-11-03 04:05:19 +01:00
r_config_get_i (core->config, "anal.from"),
r_config_get_i (core->config, "anal.to"));
} else {
r_anal_unset_limits (core->anal);
}
return 1;
}
2015-11-20 11:33:48 +03:00
static int cb_anal_jmptbl(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.jmptbl = node->i_value;
return true;
}
2015-09-30 13:10:49 +02:00
static int cb_anal_cjmpref(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.cjmpref = node->i_value;
return true;
}
static int cb_anal_jmpref(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.jmpref = node->i_value;
return true;
}
static int cb_anal_jmpabove(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.jmpabove = node->i_value;
return true;
}
static int cb_anal_followdatarefs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.followdatarefs = node->i_value;
return true;
}
static int cb_anal_searchstringrefs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.searchstringrefs = node->i_value;
return true;
}
static int cb_anal_pushret(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.pushret = node->i_value;
return true;
}
static int cb_anal_brokenrefs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.followbrokenfcnsrefs = node->i_value;
return true;
}
2015-12-10 17:46:10 +03:00
static int cb_anal_bbs_alignment(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.bbs_alignment = node->i_value;
return true;
}
2015-12-10 18:22:24 +03:00
static int cb_anal_bb_max_size(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->anal->opt.bb_max_size = node->i_value;
return true;
}
static int cb_linesto(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
ut64 from = (ut64)r_config_get_i (core->config, "lines.from");
int io_sz = r_io_size (core->io);
2015-12-22 02:30:34 +01:00
ut64 to = r_num_math (core->num, node->value);
if (to == 0) {
core->print->lines_cache_sz = -1; //r_core_lines_initcache (core, from, to);
2015-12-22 02:30:34 +01:00
return false;
}
if (to > from+io_sz) {
2015-12-22 02:30:34 +01:00
eprintf ("ERROR: \"lines.to\" can't exceed addr 0x%08"PFMT64x
" 0x%08"PFMT64x" %d\n", from, to, io_sz);
return true;
}
2015-12-22 02:30:34 +01:00
if (to > from) {
core->print->lines_cache_sz = r_core_lines_initcache (core, from, to);
//if (core->print->lines_cache_sz == -1) { eprintf ("ERROR: Can't allocate memory\n"); }
2015-12-22 02:30:34 +01:00
} else {
eprintf ("Invalid range 0x%08"PFMT64x" .. 0x%08"PFMT64x"\n", from, to);
}
return true;
}
static int cb_linesabs(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
core->print->lines_abs = node->i_value;
if (core->print->lines_abs && core->print->lines_cache_sz <= 0) {
ut64 from = (ut64)r_config_get_i (core->config, "lines.from");
ut64 to = (ut64)r_config_get_i (core->config, "lines.to");
core->print->lines_cache_sz = r_core_lines_initcache (core, from, to);
if (core->print->lines_cache_sz == -1) {
eprintf ("ERROR: \"lines.from\" and \"lines.to\" must be set\n");
} else {
eprintf ("Found %d lines\n", core->print->lines_cache_sz-1);
}
}
return true;
}
2016-09-04 13:31:25 +02:00
static char *getViewerPath() {
int i;
const char *viewers[] = {
"open",
"geeqie",
"gqview",
"eog",
2016-10-26 14:37:56 +02:00
"xdg-open",
NULL
2016-09-04 13:31:25 +02:00
};
for (i = 0; viewers[i]; i++) {
char *dotPath = r_file_path (viewers[i]);
2016-09-04 13:43:31 +02:00
if (dotPath && strcmp (dotPath, viewers[i])) {
2016-09-04 13:31:25 +02:00
return dotPath;
}
free (dotPath);
}
return NULL;
}
#define SLURP_LIMIT (10*1024*1024)
R_API int r_core_config_init(RCore *core) {
int i;
char buf[128], *p, *tmpdir;
RConfig *cfg = core->config = r_config_new (core);
2016-07-03 20:05:01 +02:00
if (!cfg) {
return 0;
}
cfg->cb_printf = r_cons_printf;
cfg->num = core->num;
2014-12-11 16:33:32 +02:00
/* pdb */
SETPREF("pdb.useragent", "Microsoft-Symbol-Server/6.11.0001.402", "User agent for Microsoft symbol server");
SETPREF("pdb.server", "https://msdl.microsoft.com/download/symbols", "Base URL for Microsoft symbol server");
2015-05-25 17:48:43 +03:00
SETI("pdb.extract", 1, "Avoid extract of the pdb file, just download");
2014-12-11 16:33:32 +02:00
/* anal */
2017-03-24 10:46:13 +01:00
SETPREF("anal.fcnprefix", "fcn", "Prefix new function names with this");
SETPREF("anal.a2f", "false", "Use the new WIP analysis algorithm (core/p/a2f), anal.depth ignored atm");
SETICB("anal.gp", 0, (RConfigCallback)&cb_anal_gp, "Set the value of the GP register (MIPS)");
SETCB("anal.limits", "false", (RConfigCallback)&cb_anal_limits, "Restrict analysis to address range [anal.from:anal.to]");
SETICB("anal.from", -1, (RConfigCallback)&cb_anal_from, "Lower limit on the address range for analysis");
SETICB("anal.to", -1, (RConfigCallback)&cb_anal_from, "Upper limit on the address range for analysis");
2016-12-12 23:57:04 +01:00
SETI("anal.timeout", 0, "Upper limit on the address range for analysis");
2014-11-03 04:05:19 +01:00
SETCB("anal.eobjmp", "false", &cb_analeobjmp, "jmp is end of block mode (option)");
2015-12-14 11:18:26 +01:00
SETCB("anal.afterjmp", "true", &cb_analafterjmp, "Continue analysis after jmp/ujmp");
2014-10-09 18:43:57 +02:00
SETI("anal.depth", 16, "Max depth at code analysis"); // XXX: warn if depth is > 50 .. can be problematic
SETICB("anal.sleep", 0, &cb_analsleep, "Sleep N usecs every so often during analysis. Avoid 100% CPU usage");
SETPREF("anal.calls", "false", "Make basic af analysis walk into calls");
2016-03-22 02:00:42 +01:00
SETPREF("anal.autoname", "true", "Automatically set a name for the functions, may result in some false positives");
SETPREF("anal.hasnext", "false", "Continue analysis after each function");
SETPREF("anal.esil", "false", "Use the new ESIL code analysis");
SETPREF("anal.strings", "false", "Identify and register strings during analysis (aar only)");
2016-06-26 01:52:53 +02:00
SETPREF("anal.vars", "true", "Analyze local variables and arguments");
SETPREF("anal.vinfun", "true", "Search values in functions (aav) (false by default to only find on non-code)");
2016-06-10 15:31:38 +02:00
SETPREF("anal.vinfunrange", "false", "Search values outside function ranges (requires anal.vinfun=false)\n");
SETCB("anal.nopskip", "true", &cb_analnopskip, "Skip nops at the beginning of functions");
SETCB("anal.hpskip", "false", &cb_analhpskip, "Skip `mov reg, reg` and `lea reg, [reg] at the beginning of functions");
SETCB("anal.noncode", "false", &cb_analnoncode, "Analyze data as code");
SETCB("anal.arch", R_SYS_ARCH, &cb_analarch, "Specify the anal.arch to use");
SETCB("anal.cpu", R_SYS_ARCH, &cb_analcpu, "Specify the anal.cpu to use");
2013-11-05 02:58:00 +01:00
SETPREF("anal.prelude", "", "Specify an hexpair to find preludes in code");
SETCB("anal.split", "true", &cb_analsplit, "Split functions into basic blocks in analysis");
SETCB("anal.recont", "false", &cb_analrecont, "End block after splitting a basic block instead of error"); // testing
SETCB("anal.trace", "false", &cb_anal_trace, "Record ESIL trace in log database");
2013-11-05 02:58:00 +01:00
SETI("anal.ptrdepth", 3, "Maximum number of nested pointers to follow in analysis");
SETICB("anal.maxreflines", 0, &cb_analmaxrefs, "Maximum number of reflines to be analyzed and displayed in asm.lines with pd");
2013-11-05 02:58:00 +01:00
2015-11-20 11:33:48 +03:00
SETCB("anal.jmptbl", "false", &cb_anal_jmptbl, "Analyze jump tables in switch statements");
SETCB("anal.cjmpref", "false", &cb_anal_cjmpref, "Create references for conditional jumps");
SETCB("anal.jmpref", "true", &cb_anal_jmpref, "Create references for unconditional jumps");
SETCB("anal.jmpabove", "true", &cb_anal_jmpabove, "Jump above function pointer");
SETCB("anal.datarefs", "false", &cb_anal_followdatarefs, "Follow data references for code coverage");
SETCB("anal.brokenrefs", "false", &cb_anal_brokenrefs, "Follow function references as well if function analysis was failed");
SETCB("anal.searchstringrefs", "false", &cb_anal_searchstringrefs, "Search string references in data references");
SETCB("anal.bb.split", "true", &cb_analbbsplit, "Use the experimental basic block split for JMPs");
SETCB("anal.bb.align", "0x10", &cb_anal_bbs_alignment, "Possible space between basic blocks");
SETCB("anal.bb.maxsize", "1024", &cb_anal_bb_max_size, "Maximum basic block size");
SETCB("anal.pushret", "false", &cb_anal_pushret, "Analyze push+ret as jmp");
SETPREF("esil.prestep", "true", "Step before esil evaluation in `de` commands");
SETPREF("esil.fillstack", "", "Initialize ESIL stack with (random, debrujn, sequence, zeros, ...)");
SETICB("esil.verbose", 0, &cb_esilverbose, "Show ESIL verbose level (0, 1, 2)");
SETICB("esil.gotolimit", core->anal->esil_goto_limit, &cb_gotolimit, "Maximum number of gotos per ESIL expression");
SETICB("esil.stack.depth", 32, &cb_esilstackdepth, "Number of elements that can be pushed on the esilstack");
2017-03-27 04:03:53 +02:00
SETI("esil.stack.size", 0xf0000, "Number of elements that can be pushed on the esilstack");
SETI("esil.stack.addr", 0x100000, "Number of elements that can be pushed on the esilstack");
SETPREF("esil.stack.pattern", "0", "Specify fill pattern to initialize the stack (0, w, d, i)");
2015-03-12 16:45:23 +01:00
/* asm */
2013-11-05 02:58:00 +01:00
//asm.os needs to be first, since other asm.* depend on it
SETCB("asm.os", R_SYS_OS, &cb_asmos, "Select operating system (kernel) (linux, darwin, w32,..)");
SETI("asm.maxrefs", 5, "Maximum number of xrefs to be displayed as list (use columns above)");
SETCB("asm.invhex", "false", &cb_asm_invhex, "Show invalid instructions as hexadecimal numbers");
SETPREF("asm.bytes", "true", "Display the bytes of each instruction");
SETPREF("asm.flagsinbytes", "false", "Display flags inside the bytes space");
2015-12-17 20:18:50 +01:00
SETICB("asm.midflags", 1, &cb_midflags, "Realign disassembly if there is a flag in the middle of an instruction");
2015-08-21 22:58:21 -07:00
SETPREF("asm.cmtflgrefs", "true", "Show comment flags associated to branch reference");
SETPREF("asm.cmtright", "true", "Show comments at right of disassembly if they fit in screen");
SETI("asm.cmtcol", 70, "Align comments at column 60");
SETICB("asm.pcalign", 0, &cb_asm_pcalign, "Only recognize as valid instructions aligned to this value");
SETPREF("asm.calls", "true", "Show callee function related info as comments in disasm");
SETPREF("asm.bbline", "false", "Show empty line after every basic block");
2013-11-05 02:58:00 +01:00
SETPREF("asm.comments", "true", "Show comments in disassembly view");
SETPREF("asm.jmphints", "true", "Show jump hints [numbers] in disasm");
2016-09-06 02:48:01 +02:00
SETPREF("asm.leahints", "false", "Show LEA hints [numbers] in disasm");
SETPREF("asm.slow", "true", "Perform slow analysis operations in disasm");
2013-11-05 02:58:00 +01:00
SETPREF("asm.decode", "false", "Use code analysis as a disassembler");
SETPREF("asm.flgoff", "false", "Show offset in flags");
SETPREF("asm.indent", "false", "Indent disassembly based on reflines depth");
SETI("asm.indentspace", 2, "How many spaces to indent the code");
2013-11-05 02:58:00 +01:00
SETPREF("asm.dwarf", "false", "Show dwarf comment at disassembly");
SETPREF("asm.dwarf.abspath", "false", "Show absolute path in asm.dwarf");
SETPREF("asm.dwarf.file", "true", "Show filename of asm.dwarf in pd");
SETPREF("asm.esil", "false", "Show ESIL instead of mnemonic");
SETPREF("asm.nodup", "false", "Do not show dupped instructions (collapse disasm)");
2015-09-11 23:46:09 +02:00
SETPREF("asm.emu", "false", "Run ESIL emulation analysis on disasm");
SETCB("asm.emustr", "false", &cb_emustr, "Show only strings if any in the asm.emu output");
SETPREF("asm.emuwrite", "false", "Allow asm.emu to modify memory (WARNING)");
SETCB("asm.emuskip", "ds", &cb_emuskip, "Skip metadata of given types in asm.emu (see e asm.emuskip=?)");
SETPREF("asm.filter", "true", "Replace numeric values by flags (e.g. 0x4003e0 -> sym.imp.printf)");
SETPREF("asm.fcnlines", "true", "Show function boundary lines");
2013-11-05 02:58:00 +01:00
SETPREF("asm.flags", "true", "Show flags");
SETPREF("asm.lbytes", "true", "Align disasm bytes to left");
SETPREF("asm.lines", "true", "Show ASCII-art lines at disassembly");
SETPREF("asm.lines.call", "false", "Enable call lines");
SETPREF("asm.lines.ret", "false", "Show separator lines after ret");
SETPREF("asm.linesout", "true", "Show out of block lines");
SETPREF("asm.linesright", "false", "Show lines before opcode instead of offset");
SETPREF("asm.lineswide", "false", "Put a space between lines");
2014-09-17 11:01:36 +02:00
SETICB("asm.lineswidth", 7, &cb_asmlineswidth, "Number of columns for program flow arrows");
2013-11-05 02:58:00 +01:00
SETPREF("asm.middle", "false", "Allow disassembling jumps in the middle of an instruction");
SETPREF("asm.offset", "true", "Show offsets at disassembly");
SETPREF("asm.spacy", "false", "Spacy disasm after calls and before flags");
SETPREF("asm.reloff", "false", "Show relative offsets instead of absolute address in disasm");
SETPREF("asm.reloff.flags", "false", "Show relative offsets to flags (not only functions)");
2014-11-22 05:39:52 +01:00
SETPREF("asm.section", "false", "Show section name before offset");
SETI("asm.section.col", 20, "Columns width to show asm.section");
SETCB("asm.section.sub", "false", &cb_asmsecsub, "Show offsets in disasm prefixed with section/map name");
SETPREF("asm.pseudo", "false", "Enable pseudo syntax");
2013-11-05 02:58:00 +01:00
SETPREF("asm.size", "false", "Show size of opcodes in disassembly (pd)");
SETPREF("asm.stackptr", "false", "Show stack pointer at disassembly");
SETPREF("asm.cyclespace", "false", "Indent instructions depending on CPU-cycles");
SETPREF("asm.cycles", "false", "Show CPU-cycles taken by instruction at disassembly");
SETI("asm.tabs", 0, "Use tabs in disassembly");
SETPREF("asm.tabsonce", "false", "Only tabulate the opcode, not the arguments");
SETI("asm.tabsoff", 0, "tabulate spaces after the offset");
2014-07-02 18:12:07 +02:00
SETPREF("asm.trace", "false", "Show execution traces for each opcode");
SETPREF("asm.tracespace", "false", "Indent disassembly with trace.count information");
2013-11-05 02:58:00 +01:00
SETPREF("asm.ucase", "false", "Use uppercase syntax at disassembly");
2016-11-04 03:56:42 +01:00
SETPREF("asm.capitalize", "false", "Use camelcase at disassembly");
SETPREF("asm.vars", "true", "Show local function variables in disassembly");
SETPREF("asm.varxs", "false", "Show accesses of local variables");
2013-11-05 02:58:00 +01:00
SETPREF("asm.varsub", "true", "Substitute variables in disassembly");
SETPREF("asm.varsum", "false", "Show variables summary instead of full list in disasm");
SETPREF("asm.varsub_only", "true", "Substitute the entire variable expression with the local variable name (e.g. [local10h] instead of [ebp+local10h])");
SETPREF("asm.relsub", "true", "Substitute pc relative expressions in disasm");
SETPREF("asm.cmtfold", "false", "Fold comments, toggle with Vz");
2015-10-03 13:52:52 +02:00
SETPREF("asm.family", "false", "Show family name in disasm");
SETPREF("asm.symbol", "false", "Show symbol+delta instead of absolute offset");
SETI("asm.symbol.col", 40, "Columns width to show asm.section");
SETCB("asm.assembler", "", &cb_asmassembler, "Set the plugin name to use when assembling");
2016-10-27 01:56:38 +02:00
SETPREF("asm.minicols", "false", "Only show the instruction in the column disasm");
2017-01-24 13:57:17 +01:00
SETCB("asm.cpu", R_SYS_ARCH, &cb_asmcpu, "Set the kind of asm.arch cpu");
SETCB("asm.arch", R_SYS_ARCH, &cb_asmarch, "Set the arch to be used by asm");
SETCB("asm.features", "", &cb_asmfeatures, "Specify supported features by the target CPU (=? for help)");
2013-11-05 02:58:00 +01:00
SETCB("asm.parser", "x86.pseudo", &cb_asmparser, "Set the asm parser to use");
SETCB("asm.segoff", "false", &cb_segoff, "Show segmented address in prompt (x86-16)");
2016-11-01 23:30:36 +01:00
SETCB("asm.decoff", "false", &cb_decoff, "Show segmented address in prompt (x86-16)");
2013-11-05 02:58:00 +01:00
SETCB("asm.syntax", "intel", &cb_asmsyntax, "Select assembly syntax");
SETI("asm.nbytes", 6, "Number of bytes for each opcode at disassembly");
SETPREF("asm.bytespace", "false", "Separate hexadecimal bytes with a whitespace");
2015-09-01 03:13:16 +02:00
#if R_SYS_BITS == R_SYS_BITS_64
SETICB("asm.bits", 64, &cb_asmbits, "Word size in bits at assembler");
#else
2013-11-05 02:58:00 +01:00
SETICB("asm.bits", 32, &cb_asmbits, "Word size in bits at assembler");
2015-09-01 03:13:16 +02:00
#endif
2013-11-05 02:58:00 +01:00
SETPREF("asm.functions", "true", "Show functions in disassembly");
SETPREF("asm.fcncalls", "true", "Show functions calls");
2013-11-05 02:58:00 +01:00
SETPREF("asm.xrefs", "true", "Show xrefs in disassembly");
SETPREF("asm.demangle", "true", "Show demangled symbols in disasm");
SETPREF("asm.describe", "false", "Show opcode description");
Add asm.hints and handle CDOV deoptimization CDIV deoptimization =================== This patch implements hints in the disassembler that aim to assist the user in reading compiler-optimized divisions by analysing the involved magic number. Background ========== Since integer divisions are usually very expensive on most architectures, compilers try very hard to substitute them with cheaper operations. One of the more advanced substitutions is described in the book __Hacker's Delight__, chapter 10. An actual implementation of the described algorithm in LLVM can be found in the functions: `TargetLowering::BuildSDIV()` and `APInt::magic()`. The optimization approximately transforms e.g. ```asm xor edx, edx idiv 39 ``` into ```asm mov eax, edi mov edx, 0xd20d20d3 imul edx lea eax, [rdx + rdi] sar edi, 0x1f sar eax, 5 sub eax, edi ``` Reading the optimized version and __seeing__ the constant 39 seems difficult. Therefore I try to provide a small hint to the user. Limitations =========== * The current implementation only takes the magic number into account, therefore it may result in false positives. * Due to the nature of the optimization, the given hint may be off by a power of two. Fixing this would require to analyse the following shift instructions. * The hint is only shown in the line containing the magic number. The user still has to know which of the following instructions belong to the optimization. TODO ==== * Implement the corresponding analysis for unsigned integers * Implement the corresponding analysis for 64-bit integers. * Improve the heuristic by also looking at the next few instructions. ( I don't really know how to iterate over the instructions in the disassember in a non-deprecated way. Maybe someone can drop me a hint? ) * Implement an exact analysis using the actual dataflow in radeco and use it to revert the optimization. ( I suppose this is outside the scope of radare )
2016-06-15 15:18:04 +02:00
SETPREF("asm.hints", "false", "Show hints for magic numbers in disasm");
SETPREF("asm.marks", "true", "Show marks before the disassembly");
SETPREF("asm.cmtrefs", "false", "Show flag and comments from refs in disasm");
SETPREF("asm.cmtpatch", "false", "Show patch comments in disasm");
SETCB("bin.strpurge", "false", &cb_strpurge, "Try to purge false positive strings");
SETPREF("bin.libs", "false", "Try to load libraries after loading main binary");
SETCB("bin.strfilter", "", &cb_strfilter, "Filter strings (?:help, a:scii, e:mail, p:ath, u:rl, 8:utf8)");
SETCB("bin.filter", "true", &cb_binfilter, "Filter symbol names to fix dupped names");
SETCB("bin.force", "", &cb_binforce, "Force that rbin plugin");
SETPREF("bin.lang", "", "Language for bin.demangle");
2016-03-12 18:01:12 +01:00
SETPREF("bin.demangle", "true", "Import demangled symbols from RBin");
SETCB("bin.demanglecmd", "false", &cb_bdc, "run xcrun swift-demangle and similar if available (SLOW)");
2013-11-05 02:58:00 +01:00
/* bin */
SETI("bin.baddr", -1, "Base address of the binary");
SETI("bin.laddr", 0, "Base address for loading library ('*.so')");
SETPREF("bin.dbginfo", "true", "Load debug information on startup if available");
SETICB("bin.minstr", 0, &cb_binminstr, "Minimum string length for r_bin");
SETICB("bin.maxstr", 0, &cb_binmaxstr, "Maximum string length for r_bin");
SETICB("bin.maxstrbuf", 1024*1024*10, & cb_binmaxstrbuf, "Maximum size of range to load strings from");
2015-10-22 20:26:24 +02:00
SETCB("bin.prefix", NULL, &cb_binprefix, "Prefix all symbols/sections/relocs with a specific string");
SETCB("bin.rawstr", "false", &cb_rawstr, "Load strings from raw binaries");
2016-10-16 02:57:08 +02:00
SETCB("bin.strings", "true", &cb_binstrings, "Load strings from rbin on startup");
SETCB("bin.debase64", "false", &cb_debase64, "Try to debase64 all strings");
SETPREF("bin.classes", "true", "Load classes from rbin on startup");
2016-10-04 15:07:26 +02:00
SETPREF("bin.mergeflags", "true", "Merge symbols with the same name into the same flag");
SETCB("bin.verbose", "true", &cb_binverbose, "Show RBin warnings when loading binaries");
2013-11-05 02:58:00 +01:00
/* prj */
SETPREF("prj.name", "", "Name of current project");
SETPREF("prj.files", "false", "Save the target binary inside the project directory");
2017-03-10 09:34:19 +01:00
SETPREF("prj.git", "false", "Every project is a git repo and saving is committing");
2016-10-18 00:15:51 +02:00
SETPREF("prj.zip", "false", "Use ZIP format for project files");
SETPREF("prj.gpg", "false", "TODO: Encrypt project with GnuPGv2");
2013-11-05 02:58:00 +01:00
/* cfg */
SETPREF("cfg.plugins", "true", "Load plugins at startup");
SETCB("time.fmt", "%Y-%m-%d %H:%M:%S %z", &cb_cfgdatefmt, "Date format (%Y-%m-%d %H:%M:%S %z)");
SETICB("time.zone", 0, &cb_timezone, "Time zone, in hours relative to GMT: +2, -1,..");
SETCB("cfg.debug", "false", &cb_cfgdebug, "Debugger mode");
p = r_sys_getenv ("EDITOR");
2015-01-26 21:41:57 +03:00
#if __WINDOWS__ && !__CYGWIN__
r_config_set (cfg, "cfg.editor", p? p: "notepad");
#else
r_config_set (cfg, "cfg.editor", p? p: "vi");
#endif
free (p);
2013-11-05 02:58:00 +01:00
r_config_desc (cfg, "cfg.editor", "Select default editor program");
SETPREF("cfg.user", r_sys_whoami (buf), "Set current username/pid");
2013-11-05 02:58:00 +01:00
SETPREF("cfg.fortunes", "true", "If enabled show tips at start");
SETPREF("cfg.fortunes.type", "tips,fun", "Type of fortunes to show (tips, fun, nsfw, creepy)");
SETPREF("cfg.fortunes.clippy", "false", "Use ?E instead of ?e");
SETPREF("cfg.fortunes.tts", "false", "Speak out the fortune");
SETI("cfg.hashlimit", SLURP_LIMIT, "If the file is bigger than hashlimit, do not compute hashes");
SETPREF("cfg.prefixdump", "dump", "Filename prefix for automated dumps");
2013-11-05 02:58:00 +01:00
SETCB("cfg.sandbox", "false", &cb_cfgsanbox, "Sandbox mode disables systems and open on upper directories");
SETPREF("cfg.wseek", "false", "Seek after write");
SETCB("cfg.bigendian", "false", &cb_bigendian, "Use little (false) or big (true) endianness");
// zign
SETPREF("zign.prefix", "sign", "Default prefix for zignatures matches");
SETI("zign.maxsz", 500, "Maximum zignature length");
2017-04-05 19:15:57 +00:00
SETI("zign.minsz", 16, "Minimum zignature length for matching");
SETI("zign.mincc", 10, "Minimum cyclomatic complexity for matching");
SETPREF("zign.graph", "true", "Use graph metrics for matching");
SETPREF("zign.bytes", "true", "Use bytes patterns for matching");
SETPREF("zign.offset", "true", "Use original offset for matching");
SETPREF("zign.refs", "true", "Use references for matching");
2013-11-05 02:58:00 +01:00
/* diff */
SETCB("diff.sort", "addr", &cb_diff_sort, "Specify function diff sorting column see (e diff.sort=?)");
2013-11-05 02:58:00 +01:00
SETI("diff.from", 0, "Set source diffing address for px (uses cc command)");
SETI("diff.to", 0, "Set destination diffing address for px (uses cc command)");
2014-12-26 11:24:49 +10:30
SETPREF("diff.bare", "false", "Never show function names in diff output");
SETPREF("diff.levenstein", "false", "Use faster (and buggy) levenstein algorithm for buffer distance diffing");
2013-11-05 02:58:00 +01:00
/* dir */
SETPREF("dir.magic", R_MAGIC_PATH, "Path to r_magic files");
2015-10-23 02:58:48 +02:00
#if __WINDOWS__
SETPREF("dir.plugins", "plugins", "Path to plugin files to be loaded at startup");
#else
2013-11-05 02:58:00 +01:00
SETPREF("dir.plugins", R2_LIBDIR"/radare2/"R2_VERSION"/", "Path to plugin files to be loaded at startup");
2015-10-23 02:58:48 +02:00
#endif
SETCB("dir.source", "", &cb_dirsrc, "Path to find source files");
2013-11-05 02:58:00 +01:00
SETPREF("dir.types", "/usr/include", "Default path to look for cparse type files");
2015-01-24 21:18:26 +01:00
#if __ANDROID__
2016-11-07 22:51:23 +01:00
SETPREF("dir.projects", "/data/data/org.radare.radare2installer/radare2/projects", "Default path for projects");
#elif __WINDOWS__
SETPREF("dir.projects", "~\\"R2_HOMEDIR"\\projects", "Default path for projects");
2015-01-24 21:18:26 +01:00
#else
SETPREF("dir.projects", "~/"R2_HOMEDIR"/projects", "Default path for projects");
2015-01-24 21:18:26 +01:00
#endif
SETPREF("stack.bytes", "true", "Show bytes instead of words in stack");
SETPREF("stack.anotated", "false", "Show anotated hexdump in visual debug");
SETI("stack.size", 64, "Size in bytes of stack hexdump in visual debug");
SETI("stack.delta", 0, "Delta for the stack dump");
2015-10-13 02:18:14 +02:00
SETCB("dbg.libs", "", &cb_dbg_libs, "If set stop when loading matching libname");
SETI("dbg.hwbp", 0, "Set HW or SW breakpoints");
2015-10-13 02:18:14 +02:00
SETCB("dbg.unlibs", "", &cb_dbg_unlibs, "If set stop when unloading matching libname");
SETPREF("dbg.slow", "false", "Show stack and regs in visual mode in a slow but verbose mode");
SETPREF("dbg.bpinmaps", "true", "Force breakpoints to be inside a valid map");
SETCB("dbg.forks", "false", &cb_dbg_forks, "Stop execution if fork() is done (see dbg.threads)");
SETCB("dbg.btalgo", "fuzzy", &cb_dbg_btalgo, "Select backtrace algorithm");
SETCB("dbg.threads", "false", &cb_stopthreads, "Stop all threads when debugger breaks (see dbg.forks)");
SETCB("dbg.clone", "false", &cb_dbg_clone, "Stop execution if new thread is created");
SETCB("dbg.aftersyscall", "true", &cb_dbg_aftersc, "Stop execution before the syscall is executed (see dcs)");
SETCB("dbg.execs", "false", &cb_dbg_execs, "Stop execution if new thread is created");
SETCB("dbg.profile", "", &cb_runprofile, "Path to RRunProfile file");
2015-09-30 13:10:49 +02:00
SETCB("dbg.args", "", &cb_dbg_args, "Set the args of the program to debug");
SETCB("dbg.follow.child", "false", &cb_dbg_follow_child, "Continue tracing the child process on fork. By default the parent process is traced");
2013-11-05 02:58:00 +01:00
/* debug */
2015-10-31 01:57:52 +01:00
SETCB("dbg.status", "false", &cb_dbgstatus, "Set cmd.prompt to '.dr*' or '.dr*;drd;sr PC;pi 1;s-'");
#if DEBUGGER
2013-11-05 02:58:00 +01:00
SETCB("dbg.backend", "native", &cb_dbgbackend, "Select the debugger backend");
#else
SETCB("dbg.backend", "esil", &cb_dbgbackend, "Select the debugger backend");
#endif
2014-05-07 23:21:34 +02:00
SETCB("dbg.bep", "loader", &cb_dbgbep, "break on entrypoint (loader, entry, constructor, main)");
2016-07-03 20:05:01 +02:00
if (core->cons->rows > 30) { // HACKY
2013-11-05 02:58:00 +01:00
r_config_set_i (cfg, "dbg.follow", 64);
2016-07-03 20:05:01 +02:00
} else {
r_config_set_i (cfg, "dbg.follow", 32);
}
2013-11-05 02:58:00 +01:00
r_config_desc (cfg, "dbg.follow", "Follow program counter when pc > core->offset + dbg.follow");
SETCB("dbg.swstep", "false", &cb_swstep, "Force use of software steps (code analysis+breakpoint)");
SETPREF("dbg.trace.inrange", "false", "While tracing, avoid following calls outside specified range");
SETPREF("dbg.exitkills", "true", "Kill process on exit");
SETCB("dbg.consbreak", "false", &cb_consbreak, "SIGINT handle for attached processes");
r_config_set_getter (cfg, "dbg.swstep", (RConfigCallback)__dbg_swstep_getter);
// TODO: This should be specified at first by the debug backend when attaching
#if __arm__ || __mips__
SETICB("dbg.bpsize", 4, &cb_dbgbpsize, "Size of software breakpoints");
#else
SETICB("dbg.bpsize", 1, &cb_dbgbpsize, "Size of software breakpoints");
#endif
2015-08-22 20:19:33 +08:00
SETICB("dbg.btdepth", 128, &cb_dbgbtdepth, "Depth of backtrace");
2013-11-05 02:58:00 +01:00
SETCB("dbg.trace", "false", &cb_trace, "Trace program execution (see asm.trace)");
SETICB("dbg.trace.tag", 0, &cb_tracetag, "Trace tag");
2013-11-05 02:58:00 +01:00
/* cmd */
2016-09-04 13:31:25 +02:00
char *xdotPath = r_file_path ("xdot");
if (r_file_exists (xdotPath)) {
2016-09-03 17:57:30 +02:00
r_config_set (cfg, "cmd.graph", "ag $$ > a.dot;!xdot a.dot");
2016-07-03 20:05:01 +02:00
} else {
2016-09-03 17:57:30 +02:00
char *dotPath = r_file_path ("dot");
2016-09-04 13:31:25 +02:00
if (r_file_exists (dotPath)) {
2016-09-03 17:57:30 +02:00
R_FREE (dotPath);
2016-09-04 13:31:25 +02:00
char *viewer = getViewerPath();
if (viewer) {
char *cmd = r_str_newf ("ag $$>a.dot;!dot -Tgif -oa.gif a.dot;!%s a.gif", viewer);
r_config_set (cfg, "cmd.graph", cmd);
free (viewer);
free (cmd);
2016-09-03 17:57:30 +02:00
} else {
r_config_set (cfg, "cmd.graph", "?e cannot find a valid picture viewer");
}
} else {
r_config_set (cfg, "cmd.graph", "agf");
}
2016-09-04 13:31:25 +02:00
free (dotPath);
2016-07-03 20:05:01 +02:00
}
2016-09-04 13:31:25 +02:00
free (xdotPath);
r_config_desc (cfg, "cmd.graph", "Command executed by 'agv' command to view graphs");
SETPREF("cmd.xterm", "xterm -bg black -fg gray -e", "xterm command to spawn with V@");
SETICB("cmd.depth", 10, &cb_cmddepth, "Maximum command depth");
SETPREF("cmd.bp", "", "Run when a breakpoint is hit");
SETICB("cmd.hitinfo", 1, &cb_debug_hitinfo, "Show info when a tracepoint/breakpoint is hit");
SETPREF("cmd.times", "", "Run when a command is repeated (number prefix)");
SETPREF("cmd.stack", "", "Command to display the stack in visual debug mode");
2013-11-05 02:58:00 +01:00
SETPREF("cmd.cprompt", "", "Column visual prompt commands");
SETPREF("cmd.gprompt", "", "Graph visual prompt commands");
SETPREF("cmd.hit", "", "Run when a search hit is found");
SETPREF("cmd.open", "", "Run when file is opened");
2013-11-05 02:58:00 +01:00
SETPREF("cmd.prompt", "", "Prompt commands");
SETCB("cmd.repeat", "false", &cb_cmdrepeat, "Empty command an alias for '..' (repeat last command)");
SETPREF("cmd.fcn.new", "", "Run when new function is analyzed");
SETPREF("cmd.fcn.delete", "", "Run when a function is deleted");
SETPREF("cmd.fcn.rename", "", "Run when a function is renamed");
2013-11-05 02:58:00 +01:00
SETPREF("cmd.visual", "", "Replace current print mode");
SETPREF("cmd.vprompt", "", "Visual prompt commands");
SETCB("cmd.esil.mdev", "", &cb_cmd_esil_mdev, "Command to run when memory device address is accessed");
SETCB("cmd.esil.intr", "", &cb_cmd_esil_intr, "Command to run when an esil interrupt happens");
SETCB("cmd.esil.trap", "", &cb_cmd_esil_trap, "Command to run when an esil trap happens");
2013-11-05 02:58:00 +01:00
/* filesystem */
SETCB("fs.view", "normal", &cb_fsview, "Set visibility options for filesystems");
/* hexdump */
2017-03-24 02:57:10 +01:00
SETPREF("hex.header", "true", "Show header in hexdumps");
SETCB("hex.pairs", "true", &cb_hexpairs, "Show bytes paired in 'px' hexdump");
SETCB("hex.compact", "false", &cb_hexcompact, "Show smallest 16 byte col hexdump (60 columns)");
SETI("hex.flagsz", 0, "If non zero, overrides the flag size in pxa");
SETICB("hex.cols", 16, &cb_hexcols, "Number of columns in hexdump");
SETI("hex.depth", 5, "Maximal level of recurrence while telescoping memory");
SETPREF("hex.onechar", "false", "Number of columns in hexdump");
SETICB("hex.stride", 0, &cb_hexstride, "Line stride in hexdump (default is 0)");
SETCB("hex.comments", "true", &cb_hexcomments, "Show comments in 'px' hexdump");
2013-11-05 02:58:00 +01:00
/* http */
2016-10-15 23:42:12 +02:00
SETPREF("http.log", "true", "Show HTTP requests processed");
SETPREF("http.logfile", "", "Specify a log file instead of stderr for http requests");
SETPREF("http.cors", "false", "Enable CORS");
SETPREF("http.referer", "", "CSFR protection if set");
2014-06-22 14:57:54 +02:00
SETPREF("http.dirlist", "false", "Enable directory listing");
SETPREF("http.allow", "", "Only accept clients from the comma separated IP list");
#if __WINDOWS__
r_config_set (cfg, "http.browser", "start");
#else
2016-07-03 20:05:01 +02:00
if (r_file_exists ("/usr/bin/openURL")) { // iOS ericautils
r_config_set (cfg, "http.browser", "/usr/bin/openURL");
2016-07-03 20:05:01 +02:00
} else if (r_file_exists ("/system/bin/toolbox")) {
r_config_set (cfg, "http.browser",
2013-11-05 02:58:00 +01:00
"LD_LIBRARY_PATH=/system/lib am start -a android.intent.action.VIEW -d");
2016-07-03 20:05:01 +02:00
} else if (r_file_exists ("/usr/bin/xdg-open")) {
r_config_set (cfg, "http.browser", "xdg-open");
2016-07-03 20:05:01 +02:00
} else if (r_file_exists ("/usr/bin/open")) {
r_config_set (cfg, "http.browser", "open");
2016-07-03 20:05:01 +02:00
} else {
r_config_set (cfg, "http.browser", "firefox");
}
r_config_desc (cfg, "http.browser", "Command to open HTTP URLs");
2013-11-05 02:58:00 +01:00
#endif
SETI("http.maxsize", 0, "Maximum file size for upload");
SETPREF("http.bind", "localhost", "Server address");
SETPREF("http.homeroot", "~/.config/radare2/www", "http home root directory");
2016-04-26 03:13:00 +02:00
#if __ANDROID__
2016-11-07 22:51:23 +01:00
SETPREF("http.root", "/data/data/org.radare.radare2installer/www", "http root directory");
2016-04-26 03:13:00 +02:00
#elif __WINDOWS__
SETPREF("http.root", "www", "http root directory");
#else
2016-04-26 03:13:00 +02:00
SETPREF("http.root", R2_WWWROOT, "http root directory");
#endif
SETPREF("http.port", "9090", "HTTP server port");
SETPREF("http.maxport", "9999", "Last HTTP server port");
SETPREF("http.ui", "m", "Default webui (enyo, m, p, t)");
2017-01-09 14:43:33 +01:00
SETPREF("http.sandbox", "true", "Sandbox the HTTP server");
SETI("http.timeout", 3, "Disconnect clients after N seconds of inactivity");
SETI("http.dietime", 0, "Kill server after N seconds with no client");
SETPREF("http.verbose", "true", "Output server logs to stdout");
SETPREF("http.upget", "false", "/up/ answers GET requests, in addition to POST");
SETPREF("http.upload", "false", "Enable file uploads to /up/<filename>");
SETPREF("http.uri", "", "Address of HTTP proxy");
tmpdir = r_file_tmpdir ();
r_config_set (cfg, "http.uproot", tmpdir);
free (tmpdir);
2016-07-03 20:05:01 +02:00
r_config_desc (cfg, "http.uproot", "Path where files are uploaded");
2013-11-05 02:58:00 +01:00
/* graph */
SETPREF("graph.comments", "true", "Show disasm comments in graph");
SETPREF("graph.cmtright", "false", "Show comments at right");
SETPREF("graph.format", "dot", "Specify output format for graphs (dot, gml, gmlfcn)");
SETPREF("graph.refs", "false", "Graph references in callgraphs (.agc*;aggi)");
SETI("graph.layout", 0, "Graph layout (0=vertical, 1=horizontal)");
SETI("graph.linemode", 1, "Graph edges (0=diagonal, 1=square)");
SETPREF("graph.font", "Courier", "Font for dot graphs");
2013-11-05 02:58:00 +01:00
SETPREF("graph.offset", "false", "Show offsets in graphs");
SETPREF("graph.web", "false", "Display graph in web browser (VV)");
SETI("graph.from", UT64_MAX, "");
SETI("graph.to", UT64_MAX, "");
SETI("graph.scroll", 5, "Scroll speed in ascii-art graph");
SETPREF("graph.invscroll", "false", "Invert scroll direction in ascii-art graph");
SETPREF("graph.title", "", "Title of the graph");
2016-05-10 21:12:50 +01:00
SETPREF("graph.gv.node", "", "Graphviz node style. (color=gray, style=filled shape=box)");
SETPREF("graph.gv.edge", "", "Graphviz edge style. (arrowhead=\"vee\")");
SETPREF("graph.gv.graph", "", "Graphviz global style attributes. (bgcolor=white)");
SETPREF("graph.gv.current", "false", "Highlight the current node in graphviz graph.");
SETPREF("graph.nodejmps", "true", "Enables shortcuts for every node.");
2013-11-05 02:58:00 +01:00
/* hud */
2014-08-30 01:22:34 +02:00
SETPREF("hud.path", "", "Set a custom path for the HUD file");
2015-09-23 12:46:22 +02:00
SETCB("esil.exectrap", "false", &cb_exectrap, "trap when executing code in non-executable memory");
SETCB("esil.iotrap", "true", &cb_iotrap, "invalid read or writes produce a trap exception");
SETPREF("esil.romem", "false", "Set memory as read-only for ESIL");
SETPREF("esil.stats", "false", "Statistics from ESIL emulation stored in sdb");
2016-08-05 14:35:44 +03:00
SETPREF("esil.nonull", "false", "Prevent memory read, memory write at null pointer");
SETCB("esil.mdev.range", "", &cb_mdevrange, "Specify a range of memory to be handled by cmd.esil.mdev");
2013-11-05 02:58:00 +01:00
/* scr */
#if __EMSCRIPTEN__
2013-11-05 02:58:00 +01:00
r_config_set_cb (cfg, "scr.fgets", "true", cb_scrfgets);
#else
2013-11-05 02:58:00 +01:00
r_config_set_cb (cfg, "scr.fgets", "false", cb_scrfgets);
#endif
r_config_desc (cfg, "scr.fgets", "Use fgets() instead of dietline for prompt input");
SETCB("scr.echo", "false", &cb_screcho, "Show rcons output in realtime to stderr and buffer");
SETICB("scr.linesleep", 0, &cb_scrlinesleep, "Flush sleeping some ms in every line");
SETICB("scr.pagesize", 1, &cb_scrpagesize, "Flush in pages when scr.linesleep is != 0");
SETCB("scr.flush", "false", &cb_scrflush, "Force flush to console in realtime (breaks scripting)");
/* TODO: rename to asm.color.ops ? */
2016-10-06 02:40:26 +02:00
SETPREF("scr.zoneflags", "true", "Show zoneflags in visual mode before the title (see fz?)");
SETPREF("scr.color.ops", "true", "Colorize numbers and registers in opcodes");
SETPREF("scr.color.bytes", "true", "Colorize bytes that represent the opcodes of the instruction");
2015-11-01 05:10:49 +01:00
#if __WINDOWS__ && !__CYGWIN__
SETCB("scr.ansicon", r_str_bool (r_cons_singleton()->ansicon),
&scr_ansicon, "Use ANSICON mode or not on Windows");
#endif
#if __ANDROID__
SETPREF("scr.responsive", "true", "Auto-adjust Visual depending on screen (e.g. unset asm.bytes)");
#else
SETPREF("scr.responsive", "false", "Auto-adjust Visual depending on screen (e.g. unset asm.bytes)");
#endif
SETPREF("scr.wheelnkey", "false", "Use sn/sp and scr.nkey on wheel instead of scroll");
SETPREF("scr.wheel", "true", "Mouse wheel in Visual; temporaryly disable/reenable by right click/Enter)");
SETPREF("scr.atport", "false", "V@ starts a background http server and spawns an r2 -C");
SETI("scr.wheelspeed", 4, "Mouse wheel speed");
// DEPRECATED: USES hex.cols now SETI("scr.colpos", 80, "Column position of cmd.cprompt in visual");
2016-12-18 00:55:10 +01:00
SETCB("scr.breakword", "", &cb_scrbreakword, "Emulate console break (^C) when a word is printed (useful for pD)");
SETICB("scr.columns", 0, &cb_scrcolumns, "Force console column count (width)");
SETCB("scr.rows", "0", &cb_scrrows, "Force console row count (height) ");
SETICB("scr.rows", 0, &cb_rows, "Force console row count (height) (duplicate?)");
SETCB("scr.fps", "false", &cb_fps, "Show FPS in Visual");
SETICB("scr.fix.rows", 0, &cb_fixrows, "Workaround for Linux TTY");
SETICB("scr.fix.columns", 0, &cb_fixcolumns, "Workaround for Prompt iOS SSH client");
SETCB("scr.highlight", "", &cb_scrhighlight, "Highlight that word at RCons level");
SETCB("scr.interactive", "true", &cb_scrint, "Start in interactive mode");
SETI("scr.feedback", 1, "Set visual feedback level (1=arrow on jump, 2=every key (useful for videos))");
SETCB("scr.html", "false", &cb_scrhtml, "Disassembly uses HTML syntax");
2017-02-03 15:32:35 +00:00
SETCB("scr.nkey", "flag", &cb_scrnkey, "Affects n/N visual cmds. Select visual seek mode (fun, hit, flag)");
SETCB("scr.pager", "", &cb_pager, "Select pager program (when output overflows the window)");
SETPREF("scr.randpal", "false", "Random color palete or just get the next one from 'eco'");
SETPREF("scr.pipecolor", "false", "Enable colors when using pipes");
SETPREF("scr.promptfile", "false", "Show user prompt file (used by r2 -q)");
2015-08-11 11:49:56 +02:00
SETPREF("scr.promptflag", "false", "Show flag name in the prompt");
SETPREF("scr.promptsect", "false", "Show section name in the prompt");
SETPREF("scr.tts", "false", "Use tts if available by a command (see ic)");
SETCB("scr.prompt", "true", &cb_scrprompt, "Show user prompt (used by r2 -q)");
SETCB("scr.tee", "", &cb_teefile, "Pipe output to file of this name");
2013-11-05 02:58:00 +01:00
SETPREF("scr.seek", "", "Seek to the specified address on startup");
2015-01-26 21:41:57 +03:00
#if __WINDOWS__ && !__CYGWIN__
2013-11-05 02:58:00 +01:00
r_config_set_cb (cfg, "scr.rgbcolor", "false", &cb_rgbcolors);
#else
2013-11-05 02:58:00 +01:00
r_config_set_cb (cfg, "scr.rgbcolor", "true", &cb_rgbcolors);
#endif
r_config_desc (cfg, "scr.rgbcolor", "Use RGB colors (not available on Windows)");
2013-11-05 02:58:00 +01:00
SETCB("scr.truecolor", "false", &cb_truecolor, "Manage color palette (0: ansi 16, 1: 256, 2: 16M)");
SETCB("scr.color", (core->print->flags&R_PRINT_FLAGS_COLOR)?"true":"false", &cb_color, "Enable colors");
SETCB("scr.null", "false", &cb_scrnull, "Show no output");
SETCB("scr.utf8", r_cons_is_utf8()?"true":"false",
&cb_utf8, "Show UTF-8 characters instead of ANSI");
SETPREF("scr.histsave", "true", "Always save history on exit");
2013-11-05 02:58:00 +01:00
/* search */
SETCB("search.contiguous", "true", &cb_contiguous, "Accept contiguous/adjacent search hits");
2013-11-05 02:58:00 +01:00
SETICB("search.align", 0, &cb_searchalign, "Only catch aligned search hits");
SETI("search.chunk", 0, "Chunk size for /+ (default size is asm.bits/8");
SETI("search.esilcombo", 8, "Stop search after N consecutive hits");
2013-11-05 02:58:00 +01:00
SETI("search.count", 0, "Start index number at search hits");
SETI("search.distance", 0, "Search string distance");
SETPREF("search.flags", "true", "All search results are flagged, otherwise only printed");
2016-02-12 11:37:48 -06:00
SETPREF("search.overlap", "false", "Look for overlapped search hits");
SETI("search.maxhits", 0, "Maximum number of hits (0: no limit)");
2013-11-05 02:58:00 +01:00
SETI("search.from", -1, "Search start address");
2015-10-02 02:20:09 -04:00
SETCB("search.in", "file", &cb_searchin, "Specify search boundaries (raw, block, file, section, range)");
2015-02-03 00:46:44 +01:00
SETICB("search.kwidx", 0, &cb_search_kwidx, "Store last search index count");
2013-11-05 02:58:00 +01:00
SETPREF("search.prefix", "hit", "Prefix name in search hits label");
SETPREF("search.show", "true", "Show search results");
2013-11-05 02:58:00 +01:00
SETI("search.to", -1, "Search end address");
/* rop */
SETI("rop.len", 5, "Maximum ROP gadget length");
SETPREF("rop.db", "true", "Store rop search results in sdb");
SETPREF("rop.subchains", "false", "Display every length gadget from rop.len=X to 2 in /Rl");
SETPREF("rop.conditional", "false", "Include conditional jump, calls and returns in ropsearch");
SETPREF("rop.nx", "false", "Include NX/XN/XD sections in ropsearch");
2015-09-30 23:47:23 -04:00
SETPREF("rop.comments", "false", "Display comments in rop search output");
2013-11-05 02:58:00 +01:00
/* io */
SETICB("io.enforce", 0, &cb_ioenforce, "Honor IO section permissions for 1=read , 2=write, 0=none");
2013-11-05 02:58:00 +01:00
SETCB("io.buffer", "false", &cb_iobuffer, "Load and use buffer cache if enabled");
SETCB("io.sectonly", "false", &cb_iosectonly, "Only read from sections (if any)");
2013-11-05 02:58:00 +01:00
SETI("io.buffer.from", 0, "Lower address of buffered cache");
SETI("io.buffer.to", 0, "Higher address of buffered cache");
SETCB("io.cache", "false", &cb_iocache, "Enable cache for io changes");
2014-06-10 11:20:17 +02:00
SETCB("io.ff", "true", &cb_ioff, "Fill invalid buffers with 0xff instead of returning error");
SETICB("io.0xff", 0xff, &cb_io_oxff, "Use this value instead of 0xff to fill unallocated areas");
SETCB("io.aslr", "false", &cb_ioaslr, "Disable ASLR for spawn and such");
SETCB("io.va", "true", &cb_iova, "Use virtual address layout");
2016-11-04 01:30:35 +01:00
SETCB("io.pava", "false", &cb_iopava, "Use EXPERIMENTAL paddr -> vaddr address mode");
SETCB("io.autofd", "true", &cb_ioautofd, "Change fd when opening a new file");
SETCB("io.vio", "false", &cb_iovio, "Enable the new vio (reading only) (WIP)");
2013-11-05 02:58:00 +01:00
/* file */
SETPREF("file.desc", "", "User defined file description (used by projects)");
SETPREF("file.md5", "", "MD5 sum of current file");
SETPREF("file.info", "true", "RBin info loaded");
SETPREF("file.offset", "", "Offset where the file will be mapped at");
2013-11-05 02:58:00 +01:00
SETPREF("file.path", "", "Path of current file");
SETPREF("file.sha1", "", "SHA1 hash of current file");
2013-11-05 02:58:00 +01:00
SETPREF("file.type", "", "Type of current file");
2014-04-28 11:37:48 +02:00
SETCB("file.loadmethod", "fail", &cb_fileloadmethod, "What to do when load addresses overlap: fail, overwrite, or append (next available)");
SETI("file.loadalign", 1024, "Alignment of load addresses");
SETI("file.openmany", 1, "Maximum number of files opened at once");
SETPREF("file.nowarn", "true", "Suppress file loading warning messages");
SETPREF("file.location", "", "Is the file 'local', 'remote', or 'memory'");
2013-11-05 02:58:00 +01:00
/* magic */
SETI("magic.depth", 100, "Recursivity depth in magic description strings");
/* rap */
SETPREF("rap.loop", "true", "Run rap as a forever-listening daemon");
/* nkeys */
SETPREF("key.s", "", "override step into action");
SETPREF("key.S", "", "override step over action");
2016-07-03 20:05:01 +02:00
for (i = 1; i < 13; i++) {
snprintf (buf, sizeof (buf), "key.f%d", i);
2016-07-03 20:05:01 +02:00
snprintf (buf + 10, sizeof (buf) - 10,
2013-11-05 02:58:00 +01:00
"Run this when F%d key is pressed in visual mode", i);
switch (i) {
2013-11-05 02:58:00 +01:00
default: p = ""; break;
}
r_config_set (cfg, buf, p);
r_config_desc (cfg, buf, buf+10);
}
2013-11-05 02:58:00 +01:00
/* zoom */
2013-11-05 02:58:00 +01:00
SETCB("zoom.byte", "h", &cb_zoombyte, "Zoom callback to calculate each byte (See pz? for help)");
SETI("zoom.from", 0, "Zoom start address");
SETI("zoom.maxsz", 512, "Zoom max size of block");
SETI("zoom.to", 0, "Zoom end address");
/* lines */
2015-12-22 02:30:34 +01:00
SETI("lines.from", 0, "Start address for line seek");
SETCB("lines.to", "$s", &cb_linesto, "End address for line seek");
SETCB("lines.abs", "false", &cb_linesabs, "Enable absolute line numbers");
2015-09-14 12:35:38 +02:00
r_config_lock (cfg, true);
return true;
}