R_API RSpace *r_spaces_add(RSpaces *sp, const char *name) { r_return_val_if_fail (sp, NULL); if (!name || !*name || *name == '*') { return NULL; } RSpace *s = r_spaces_get (sp, name); if (s) { return s; } s = R_NEW0 (RSpace); if (!s) { return NULL; } s->name = strdup (name); if (!s->name) { free (s); return NULL; } r_rbtree_insert (&sp->spaces, s, &s->rb, space_cmp); return s; }
static int flag_to_flag(RCore *core, const char *glob) { r_return_val_if_fail (glob, 0); glob = r_str_trim_ro (glob); struct flag_to_flag_t u = { .next = UT64_MAX, .offset = core->offset }; r_flag_foreach_glob (core->flags, glob, flag_to_flag_foreach, &u); if (u.next != UT64_MAX && u.next > core->offset) { return u.next - core->offset; } return 0; } static void cmd_flag_tags (RCore *core, const char *input) { char mode = input[1]; for (; *input && !IS_WHITESPACE (*input); input++) {} char *inp = strdup (input); char *arg = r_str_trim (inp); if (!*arg && !mode) { const char *tag; RListIter *iter; RList *list = r_flag_tags_list (core->flags); r_list_foreach (list, iter, tag) { r_cons_printf ("%s\n", tag); } r_list_free (list); free (inp); return; }
// - name should be allocated on the heap R_API char *r_bin_filter_name(RBinFile *bf, Sdb *db, ut64 vaddr, char *name) { r_return_val_if_fail (db && name, NULL); char *resname = name; const char *uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, resname); ut32 vhash = sdb_hash (uname); // vaddr hash - unique ut32 hash = sdb_hash (resname); // name hash - if dupped and not in unique hash must insert int count = sdb_num_inc (db, sdb_fmt ("%x", hash), 1, 0); if (sdb_exists (db, sdb_fmt ("%x", vhash))) { // TODO: symbol is dupped, so symbol can be removed! return resname; } sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0); if (vaddr) { char *p = hashify (resname, vaddr); if (p) { resname = p; } } if (count > 1) { char *p = r_str_appendf (resname, "_%d", count - 1); if (p) { resname = p; } // two symbols at different addresses and same name wtf // eprintf ("Symbol '%s' dupped!\n", sym->name); } return resname; }
R_API bool r_spaces_init(RSpaces *sp, const char *name) { r_return_val_if_fail (sp && name, false); sp->name = strdup (name); if (!sp->name) { goto fail; } sp->spaces = NULL; sp->current = NULL; sp->spacestack = r_list_new (); if (!sp->spacestack) { goto fail; } sp->event = r_event_new (sp); if (!sp->event) { goto fail; } return true; fail: r_spaces_free (sp); return false; }
static void *load_buffer(RBinFile *bf, RBuffer *buf, ut64 loadaddr, Sdb *sdb) { r_return_val_if_fail (bf && buf && r_buf_size (buf) != UT64_MAX, NULL); if (!check_bytes_buf (buf)) { return NULL; } return r_bin_wasm_init (bf, buf); }
R_API PJ *pj_k(PJ *j, const char *k) { r_return_val_if_fail (j && k, NULL); j->is_key = false; pj_s (j, k); pj_raw (j, ":"); j->is_first = false; j->is_key = true; return j; }
R_API PJ *pj_end(PJ *j) { r_return_val_if_fail (j && j->level > 0, NULL); if (--j->level < 1) { char msg[2] = { j->braces[j->level], 0 }; pj_raw (j, msg); j->level = 0; return j; } char msg[2] = { j->braces[j->level], 0 }; pj_raw (j, msg); return j; }
R_API int r_asm_op_set_hexbuf(RAsmOp *op, const ut8 *buf, int len) { r_return_val_if_fail (op && buf && len >= 0, 0); char *hex = malloc (len * 4 + 1); if (hex) { (void)r_hex_bin2str (buf, len, hex); int olen = r_asm_op_set_hex (op, hex); free (hex); return olen; } return 0; // TODO: update the op->buf too? }
/* * Provides the info about the binary file * @param RBinFile to extract the data from * @return RBinInfo file with the info */ static RBinInfo *info(RBinFile *bf) { r_return_val_if_fail (bf && bf->o && bf->o->bin_obj, NULL); RBinInfo *ret = R_NEW0 (RBinInfo); if (!ret) { return NULL; } ret->file = bf->file? strdup (bf->file): NULL; ret->type = strdup ("QNX Executable"); ret->bclass = strdup ("qnx"); ret->machine = strdup ("i386"); ret->rclass = strdup ("QNX"); ret->arch = strdup ("x86"); ret->os = strdup ("any"); ret->subsystem = strdup ("any"); ret->lang = "C/C++"; ret->signature = true; return ret; }
static char *hashify(char *s, ut64 vaddr) { r_return_val_if_fail (s, NULL); char *os = s; while (*s) { if (!IS_PRINTABLE (*s)) { if (vaddr && vaddr != UT64_MAX) { free (os); return r_str_newf ("_%" PFMT64d, vaddr); } ut32 hash = sdb_hash (s); free (os); return r_str_newf ("%x", hash); } s++; } return os; }
R_API RList *r_sign_fcn_vars(RAnal *a, RAnalFunction *fcn) { r_return_val_if_fail (a && fcn, NULL); RCore *core = a->coreb.core; if (!core) { return NULL; } RListIter *iter; RAnalVar *var; RList *ret = r_list_newf ((RListFree) free); if (!ret) { return NULL; } RList *reg_vars = r_anal_var_list (core->anal, fcn, R_ANAL_VAR_KIND_REG); RList *spv_vars = r_anal_var_list (core->anal, fcn, R_ANAL_VAR_KIND_SPV); RList *bpv_vars = r_anal_var_list (core->anal, fcn, R_ANAL_VAR_KIND_BPV); r_list_foreach (bpv_vars, iter, var) { r_list_append (ret, r_str_newf ("b%d", var->delta)); }
static int r_debug_bf_reg_read(RDebug *dbg, int type, ut8 *buf, int size) { r_return_val_if_fail (dbg && buf && size > 0, -1); if (!is_io_bf (dbg)) { return 0; } if (!(dbg->iob.io) || !(dbg->iob.io->desc) || !(dbg->iob.io->desc->data)) { return 0; } RIOBdescbg *o = dbg->iob.io->desc->data; r.pc = o->bfvm->eip; r.ptr = o->bfvm->ptr; r.sp = o->bfvm->esp; r.scr = o->bfvm->screen; r.scri = o->bfvm->screen_idx; r.inp = o->bfvm->input; r.inpi = o->bfvm->input_idx; r.mem = o->bfvm->base; r.memi = o->bfvm->ptr; memcpy (buf, &r, sizeof (r)); //r_io_system (dbg->iob.io, "dr"); return sizeof (r); }
static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data, int datalen, RBinArchOptions *opt) { ut32 filesize, code_va, code_pa, phoff; ut32 p_start, p_phoff, p_phdr; ut32 p_ehdrsz, p_phdrsz; ut16 ehdrsz, phdrsz; ut32 p_vaddr, p_paddr, p_fs, p_fs2; ut32 baddr; int is_arm = 0; RBuffer *buf = r_buf_new (); r_return_val_if_fail (bin && opt && opt->arch, NULL); is_arm = !strcmp (opt->arch, "arm"); // XXX: hardcoded if (is_arm) { baddr = 0x40000; } else { baddr = 0x8048000; } #define B(x,y) r_buf_append_bytes(buf,(const ut8*)(x),y) #define D(x) r_buf_append_ut32(buf,x) #define H(x) r_buf_append_ut16(buf,x) #define Z(x) r_buf_append_nbytes(buf,x) #define W(x,y,z) r_buf_write_at(buf,x,(const ut8*)(y),z) #define WZ(x,y) p_tmp=r_buf_size (buf);Z(x);W(p_tmp,y,strlen(y)) B ("\x7F" "ELF" "\x01\x01\x01\x00", 8); Z (8); H (2); // ET_EXEC if (is_arm) { H (40); // e_machne = EM_ARM } else { H (3); // e_machne = EM_I386 } D (1); p_start = r_buf_size (buf); D (-1); // _start p_phoff = r_buf_size (buf); D (-1); // phoff -- program headers offset D (0); // shoff -- section headers offset D (0); // flags p_ehdrsz = r_buf_size (buf); H (-1); // ehdrsz p_phdrsz = r_buf_size (buf); H (-1); // phdrsz H (1); H (0); H (0); H (0); // phdr: p_phdr = r_buf_size (buf); D (1); D (0); p_vaddr = r_buf_size (buf); D (-1); // vaddr = $$ p_paddr = r_buf_size (buf); D (-1); // paddr = $$ p_fs = r_buf_size (buf); D (-1); // filesize p_fs2 = r_buf_size (buf); D (-1); // filesize D (5); // flags D (0x1000); // align ehdrsz = p_phdr; phdrsz = r_buf_size (buf) - p_phdr; code_pa = r_buf_size (buf); code_va = code_pa + baddr; phoff = 0x34;//p_phdr ; filesize = code_pa + codelen + datalen; W (p_start, &code_va, 4); W (p_phoff, &phoff, 4); W (p_ehdrsz, &ehdrsz, 2); W (p_phdrsz, &phdrsz, 2); code_va = baddr; // hack W (p_vaddr, &code_va, 4); code_pa = baddr; // hack W (p_paddr, &code_pa, 4); W (p_fs, &filesize, 4); W (p_fs2, &filesize, 4); B (code, codelen); if (data && datalen > 0) { //ut32 data_section = buf->length; eprintf ("Warning: DATA section not support for ELF yet\n"); B (data, datalen); } return buf; }
// Returns the sections static RList* sections(RBinFile *bf) { r_return_val_if_fail (bf && bf->o, NULL); QnxObj *qo = bf->o->bin_obj; return r_list_clone (qo->sections); }
static RList *relocs(RBinFile *bf) { r_return_val_if_fail (bf && bf->o, NULL); QnxObj *qo = bf->o->bin_obj; return r_list_clone (qo->fixups); }
static bool load(RBinFile *bf) { r_return_val_if_fail (bf && bf->o, false); bf->o->bin_obj = load_buffer (bf, bf->buf, bf->o->loadaddr, bf->sdb); return bf->o->bin_obj != NULL; }
R_API int r_asm_op_get_size(RAsmOp *op) { r_return_val_if_fail (op, 1); const int len = op->size - op->payload; return R_MAX (1, len); }
R_API ut8 *r_asm_op_get_buf(RAsmOp *op) { r_return_val_if_fail (op, NULL); return (ut8*)r_strbuf_get (&op->buf); }