static Sdb *get_sdb(RBinFile *bf) { Sdb *kv = sdb_new0 (); sdb_num_set (kv, "nro_start.offset", 0, 0); sdb_num_set (kv, "nro_start.size", 16, 0); sdb_set (kv, "nro_start.format", "xxq unused mod_memoffset padding", 0); sdb_num_set (kv, "nro_header.offset", 16, 0); sdb_num_set (kv, "nro_header.size", 0x70, 0); sdb_set (kv, "nro_header.format", "xxxxxxxxxxxx magic unk size unk2 text_offset text_size ro_offset ro_size data_offset data_size bss_size unk3", 0); sdb_ns_set (bf->sdb, "info", kv); return kv; }
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 la, Sdb *sdb) { BootImageObj *bio = R_NEW0 (BootImageObj); if (!bio) return NULL; bio->kv = sdb_new0 (); if (!bio->kv) { free (bio); return NULL; } bootimg_header_load (&bio->bi, arch->buf, bio->kv); sdb_ns_set (sdb, "info", bio->kv); return bio; }
static int r_bin_mz_init(struct r_bin_mz_obj_t* bin) { bin->dos_header = NULL; bin->dos_extended_header = NULL; bin->relocation_entries = NULL; bin->kv = sdb_new0 (); if (!r_bin_mz_init_hdr (bin)) { eprintf ("Warning: File is not MZ\n"); return false; } return true; }
struct r_bin_te_obj_t* r_bin_te_new_buf(struct r_buf_t *buf) { struct r_bin_te_obj_t *bin = R_NEW0 (struct r_bin_te_obj_t); if (!bin) return NULL; bin->kv = sdb_new0 (); bin->b = r_buf_new (); bin->size = buf->length; if (!r_buf_set_bytes (bin->b, buf->buf, bin->size)){ return r_bin_te_free(bin); } if (!r_bin_te_init(bin)) return r_bin_te_free(bin); return bin; }
R_API void r_bin_filter_symbols(RBinFile *bf, RList *list) { Sdb *db = sdb_new0 (); if (db) { RListIter *iter; RBinSymbol *sym; r_list_foreach (list, iter, sym) { if (sym && sym->name && *sym->name) { r_bin_filter_sym (bf, db, sym->vaddr, sym); } } sdb_free (db); } }
static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 la, Sdb *sdb){ ArtObj *ao = R_NEW0 (ArtObj); if (!ao) { return NULL; } ao->kv = sdb_new0 (); if (!ao->kv) { free (ao); return NULL; } art_header_load (&ao->art, arch->buf, ao->kv); sdb_ns_set (sdb, "info", ao->kv); return ao; }
struct r_bin_mdmp_obj *r_bin_mdmp_new_buf(struct r_buf_t *buf) { struct r_bin_mdmp_obj *obj = R_NEW0(struct r_bin_mdmp_obj); if (!obj) return NULL; obj->b = r_buf_new_with_buf (buf); if (!obj->b) { eprintf ("r_bin_mdmp_new_buf: r_buf_new_with_buf failed\n"); r_bin_mdmp_free (obj); return NULL; } obj->kv = sdb_new0 (); if (!r_bin_mdmp_init (obj)) { r_bin_mdmp_free (obj); return NULL; } return obj; }
R_API RPrint* r_print_new() { RPrint *p = R_NEW0 (RPrint); if (!p) { return NULL; } strcpy (p->datefmt, "%Y-%m-%d %H:%M:%S %z"); r_io_bind_init (p->iob); p->pairs = true; p->resetbg = true; p->cb_printf = libc_printf; p->oprintf = nullprinter; p->bits = 32; p->stride = 0; p->bytespace = 0; p->interrupt = 0; p->big_endian = false; p->datezone = 0; p->col = 0; p->width = 78; p->cols = 16; p->cur_enabled = false; p->cur = p->ocur = -1; p->formats = sdb_new0 (); p->addrmod = 4; p->flags = R_PRINT_FLAGS_COLOR | R_PRINT_FLAGS_OFFSET | R_PRINT_FLAGS_HEADER | R_PRINT_FLAGS_ADDRMOD; p->seggrn = 4; p->zoom = R_NEW0 (RPrintZoom); p->reg = NULL; p->get_register = NULL; p->get_register_value = NULL; p->lines_cache = NULL; p->calc_row_offsets = true; p->row_offsets_sz = 0; p->row_offsets = NULL; p->vflush = true; p->screen_bounds = 0; p->esc_bslash = false; p->strconv_mode = NULL; memset (&p->consbind, 0, sizeof (p->consbind)); p->io_unalloc_ch = '.'; return p; }
int main() { #define DBFILE "___syncget.db" const char *v; Sdb *s = sdb_new0(); unlink (DBFILE); sdb_set (s, "foo", "bar", 0); eprintf ("-> %s\n", sdb_get (s, "foo", NULL)); sdb_file (s, DBFILE); sdb_sync (s); v = sdb_const_get (s, "foo", NULL); if (v && !strcmp ("bar", v)) { eprintf ("OK syncget\n"); return 0; } eprintf ("ERROR syncget: Keys not accessible after sync\n"); return 1; }
int main () { //Sdb *s = sdb_new (NULL, "/tmp/", 1); Sdb *s = sdb_new0 (); if (!s) { eprintf ("SDB FAIL\n"); } // TODO: unlink bar file" Sdb *n = sdb_ns (s, "bar", 1); if (n == NULL) { eprintf ("n = NULL!\n"); return 1; } sdb_set (n, "user.pancake", "pancake foo", 0); sdb_set (n, "user.password", "jklsdf8r3o", 0); sdb_ns_sync (s); // if "bar" file exists = WIN // return 0; }
R_API void r_anal_esil_stats(RAnalEsil *esil, int enable) { if (enable) { if (esil->stats) sdb_reset (esil->stats); else esil->stats = sdb_new0(); // reset sdb->stats esil->cb.hook_reg_read = hook_reg_read; esil->cb.hook_mem_read = hook_mem_read; esil->cb.hook_mem_write = hook_mem_write; esil->cb.hook_reg_write = hook_reg_write; esil->cb.hook_flag_read = hook_flag_read; esil->cb.hook_command = hook_command; } else { esil->cb.hook_mem_write = NULL; esil->cb.hook_flag_read = NULL; esil->cb.hook_command = NULL; sdb_free (esil->stats); esil->stats = NULL; } }
R_API RDebug *r_debug_new(int hard) { RDebug *dbg = R_NEW0 (RDebug); if (!dbg) return NULL; // R_SYS_ARCH dbg->arch = r_sys_arch_id (R_SYS_ARCH); // 0 is native by default dbg->bits = R_SYS_BITS; dbg->trace_forks = 1; dbg->trace_clone = 0; R_FREE (dbg->btalgo); dbg->trace_execs = 0; dbg->anal = NULL; dbg->snaps = r_list_newf (r_debug_snap_free); dbg->pid = -1; dbg->bpsize = 1; dbg->tid = -1; dbg->tree = r_tree_new (); dbg->tracenodes = sdb_new0 (); dbg->swstep = 0; dbg->newstate = 0; dbg->signum = 0; dbg->reason = R_DBG_REASON_UNKNOWN; dbg->stop_all_threads = R_FALSE; dbg->trace = r_debug_trace_new (); dbg->printf = (void *)printf; dbg->reg = r_reg_new (); dbg->num = r_num_new (r_debug_num_callback, dbg); dbg->h = NULL; /* TODO: needs a redesign? */ dbg->maps = r_debug_map_list_new (); dbg->maps_user = r_debug_map_list_new (); r_debug_signal_init (dbg); if (hard) { dbg->bp = r_bp_new (); r_debug_plugin_init (dbg); dbg->bp->iob.init = R_FALSE; } return dbg; }
R_API void r_cons_pal_update_event() { Sdb *db = sdb_new0 (); int i, n = 0; char **color; /* Compute cons->pal values */ for (i = 0; keys[i].name; i++) { RColor *rcolor = RCOLOR_AT (i); color = COLOR_AT (i); // Color is dynamically allocated, needs to be freed if (*color) { R_FREE (*color); } *color = r_cons_rgb_str (NULL, 0, rcolor); const char *rgb = sdb_fmt ("rgb:%02x%02x%02x", rcolor->r, rcolor->g, rcolor->b); sdb_set (db, rgb, "1", 0); } SdbList *list = sdb_foreach_list (db, true); SdbListIter *iter; SdbKv *kv; r_cons_rainbow_free (); r_cons_rainbow_new (list->length); ls_foreach (list, iter, kv) { r_cons_singleton ()->pal.rainbow[n++] = strdup (kv->key); }
static void cons_pal_update_event(RConsContext *ctx) { Sdb *db = sdb_new0 (); int i, n = 0; char **color; /* Compute cons->pal values */ for (i = 0; keys[i].name; i++) { RColor *rcolor = (RColor *) (((ut8 *) &(ctx->cpal)) + keys[i].coff); color = (char **) (((ut8 *) &(ctx->pal)) + keys[i].off); // Color is dynamically allocated, needs to be freed if (*color) { R_FREE (*color); } *color = r_cons_rgb_str_mode (ctx->color, NULL, 0, rcolor); const char *rgb = sdb_fmt ("rgb:%02x%02x%02x", rcolor->r, rcolor->g, rcolor->b); sdb_set (db, rgb, "1", 0); } SdbList *list = sdb_foreach_list (db, true); SdbListIter *iter; SdbKv *kv; r_cons_rainbow_free (ctx); r_cons_rainbow_new (ctx, list->length); ls_foreach (list, iter, kv) { ctx->pal.rainbow[n++] = strdup (sdbkv_key (kv)); }
static void *load_buffer(RBinFile *bf, RBuffer *buf, ut64 loadaddr, Sdb *sdb) { QnxObj *qo = R_NEW0 (QnxObj); lmf_record lrec; lmf_resource lres; lmf_data ldata; ut64 offset = QNX_RECORD_SIZE; RList *sections = NULL; RList *fixups = NULL; if (!qo) { goto beach; } if (!(sections = r_list_newf ((RListFree)r_bin_section_free)) || !(fixups = r_list_new ())) { goto beach; } qo->kv = sdb_new0 (); if (!qo->kv) { free (qo); goto beach; } // Read the first record if (r_buf_fread_at (bf->buf, 0, (ut8 *)&lrec, "ccss", 1) < QNX_RECORD_SIZE) { goto beach; } // Load the header lmf_header_load (&qo->lmfh, bf->buf, qo->kv); offset += lrec.data_nbytes; for (;;) { if (r_buf_fread_at (bf->buf, offset, (ut8 *)&lrec, "ccss", 1) < QNX_RECORD_SIZE) { goto beach; } offset += sizeof (lmf_record); if (lrec.rec_type == LMF_IMAGE_END_REC) { break; } else if (lrec.rec_type == LMF_RESOURCE_REC) { RBinSection *ptr = R_NEW0 (RBinSection); if (r_buf_fread_at (bf->buf, offset, (ut8 *)&lres, "ssss", 1) < sizeof (lmf_resource)) { goto beach; } if (!ptr) { goto beach; } ptr->name = strdup ("LMF_RESOURCE"); ptr->paddr = offset; ptr->vsize = lrec.data_nbytes - sizeof (lmf_resource); ptr->size = ptr->vsize; ptr->add = true; r_list_append (sections, ptr); } else if (lrec.rec_type == LMF_LOAD_REC) { RBinSection *ptr = R_NEW0 (RBinSection); if (r_buf_fread_at (bf->buf, offset, (ut8 *)&ldata, "si", 1) < sizeof (lmf_data)) { goto beach; } if (!ptr) { goto beach; } ptr->name = strdup ("LMF_LOAD"); ptr->paddr = offset; ptr->vaddr = ldata.offset; ptr->vsize = lrec.data_nbytes - sizeof (lmf_data); ptr->size = ptr->vsize; ptr->add = true; r_list_append (sections, ptr); } else if (lrec.rec_type == LMF_FIXUP_REC) { RBinReloc *ptr = R_NEW0 (RBinReloc); if (!ptr || r_buf_fread_at (bf->buf, offset, (ut8 *)&ldata, "si", 1) < sizeof (lmf_data)) { goto beach; } ptr->vaddr = ptr->paddr = ldata.offset; ptr->type = 'f'; // "LMF_FIXUP"; r_list_append (fixups, ptr); } else if (lrec.rec_type == LMF_8087_FIXUP_REC) { RBinReloc *ptr = R_NEW0 (RBinReloc); if (!ptr || r_buf_fread_at (bf->buf, offset, (ut8 *)&ldata, "si", 1) < sizeof (lmf_data)) { goto beach; } ptr->vaddr = ptr->paddr = ldata.offset; ptr->type = 'F'; // "LMF_8087_FIXUP"; r_list_append (fixups, ptr); } else if (lrec.rec_type == LMF_RW_END_REC) { r_buf_fread_at (bf->buf, offset, (ut8 *)&qo->rwend, "si", 1); } offset += lrec.data_nbytes; } sdb_ns_set (sdb, "info", qo->kv); qo->sections = sections; qo->fixups = fixups; return qo; beach: return NULL; }
R_API int r_core_pseudo_code(RCore *core, const char *input) { Sdb *db; ut64 queuegoto = 0LL; const char *blocktype = "else"; RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL); RConfigHold *hc = r_config_hold_new (core->config); if (!hc) { return false; } r_config_save_num (hc, "asm.pseudo", "asm.decode", "asm.lines", "asm.bytes", NULL); r_config_save_num (hc, "asm.offset", "asm.flags", "asm.fcnlines", "asm.comments", NULL); r_config_save_num (hc, "asm.functions", "asm.section", "asm.cmtcol", "asm.filter", NULL); r_config_save_num (hc, "scr.color", "asm.emustr", "asm.emu", "asm.emuwrite", NULL); if (!fcn) { eprintf ("Cannot find function in 0x%08"PFMT64x"\n", core->offset); r_config_hold_free (hc); return false; } r_config_set_i (core->config, "scr.color", 0); r_config_set_i (core->config, "asm.pseudo", 1); r_config_set_i (core->config, "asm.decode", 0); r_config_set_i (core->config, "asm.filter", 1); r_config_set_i (core->config, "asm.lines", 0); r_config_set_i (core->config, "asm.bytes", 0); r_config_set_i (core->config, "asm.offset", 0); r_config_set_i (core->config, "asm.flags", 0); r_config_set_i (core->config, "asm.emu", 1); r_config_set_i (core->config, "asm.emustr", 1); r_config_set_i (core->config, "asm.emuwrite", 1); r_config_set_i (core->config, "asm.fcnlines", 0); r_config_set_i (core->config, "asm.comments", 1); r_config_set_i (core->config, "asm.functions", 0); r_config_set_i (core->config, "asm.tabs", 0); r_config_set_i (core->config, "asm.section", 0); r_config_set_i (core->config, "asm.cmtcol", 30); r_core_cmd0 (core, "aeim"); db = sdb_new0 (); /* */ // walk all basic blocks // define depth level for each block // use it for indentation // asm.pseudo=true // asm.decode=true RAnalBlock *bb = r_list_first (fcn->bbs); char indentstr[1024]; int n_bb = r_list_length (fcn->bbs); r_cons_printf ("function %s () {", fcn->name); int indent = 1; int nindent = 1; do { #define I_TAB 4 #define K_MARK(x) sdb_fmt(0,"mark.%"PFMT64x,x) #define K_ELSE(x) sdb_fmt(0,"else.%"PFMT64x,x) #define K_INDENT(x) sdb_fmt(0,"loc.%"PFMT64x,x) #define SET_INDENT(x) { memset (indentstr, ' ', x*I_TAB); indentstr [(x*I_TAB)-2] = 0; } if (!bb) break; r_cons_push (); char *code = r_core_cmd_str (core, sdb_fmt (0, "pD %d @ 0x%08"PFMT64x"\n", bb->size, bb->addr)); r_cons_pop (); memset (indentstr, ' ', indent * I_TAB); indentstr [(indent * I_TAB) - 2] = 0; code = r_str_prefix_all (code, indentstr); int len = strlen (code); code[len - 1] = 0; // chop last newline //r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); //if (nindent != indent) { // r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); //} find_and_change (code, len); if (!sdb_const_get (db, K_MARK (bb->addr), 0)) { bool mustprint = !queuegoto || queuegoto != bb->addr; if (mustprint) { if (queuegoto) { r_cons_printf ("\n%s goto loc_0x%llx", indentstr, queuegoto); queuegoto = 0LL; } r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); indentstr[(indent * I_TAB) - 2] = 0; r_cons_printf ("\n%s", code); free (code); sdb_num_set (db, K_MARK (bb->addr), 1, 0); } } if (sdb_const_get (db, K_INDENT (bb->addr), 0)) { // already analyzed, go pop and continue // XXX check if cant pop //eprintf ("%s// 0x%08llx already analyzed\n", indentstr, bb->addr); ut64 addr = sdb_array_pop_num (db, "indent", NULL); if (addr == UT64_MAX) { int i; nindent = 1; for (i = indent; i != nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s}", indentstr); } r_cons_printf ("\n%sreturn;\n", indentstr); break; } if (sdb_num_get (db, K_ELSE (bb->addr), 0)) { if (!strcmp (blocktype, "else")) { r_cons_printf ("\n%s } %s {", indentstr, blocktype); } else { r_cons_printf ("\n%s } %s (?);", indentstr, blocktype); } } else { r_cons_printf ("\n%s}", indentstr); } if (addr != bb->addr) { queuegoto = addr; //r_cons_printf ("\n%s goto loc_0x%llx", indentstr, addr); } bb = r_anal_bb_from_offset (core->anal, addr); if (!bb) { eprintf ("failed block\n"); break; } //eprintf ("next is %llx\n", addr); nindent = sdb_num_get (db, K_INDENT (addr), NULL); if (indent > nindent && !strcmp (blocktype, "else")) { int i; for (i = indent; i != nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s }", indentstr); } } indent = nindent; } else { sdb_set (db, K_INDENT (bb->addr), "passed", 0); if (bb->jump != UT64_MAX) { int swap = 1; // TODO: determine which branch take first ut64 jump = swap ? bb->jump : bb->fail; ut64 fail = swap ? bb->fail : bb->jump; // if its from another function chop it! RAnalFunction *curfcn = r_anal_get_fcn_in (core->anal, jump, R_ANAL_FCN_TYPE_NULL); if (curfcn != fcn) { // chop that branch r_cons_printf ("\n // chop\n"); break; } if (sdb_get (db, K_INDENT (jump), 0)) { // already tracekd if (!sdb_get (db, K_INDENT (fail), 0)) { bb = r_anal_bb_from_offset (core->anal, fail); } } else { bb = r_anal_bb_from_offset (core->anal, jump); if (!bb) { eprintf ("failed to retrieve blcok at 0x%"PFMT64x"\n", jump); break; } if (fail != UT64_MAX) { // do not push if already pushed indent++; if (sdb_get (db, K_INDENT (bb->fail), 0)) { /* do nothing here */ eprintf ("BlockAlready 0x%"PFMT64x"\n", bb->addr); } else { // r_cons_printf (" { RADICAL %llx\n", bb->addr); sdb_array_push_num (db, "indent", fail, 0); sdb_num_set (db, K_INDENT (fail), indent, 0); sdb_num_set (db, K_ELSE (fail), 1, 0); SET_INDENT (indent); r_cons_printf ("\n%s {", indentstr); } } else { r_cons_printf ("\n%s do", indentstr); sdb_array_push_num (db, "indent", jump, 0); sdb_num_set (db, K_INDENT (jump), indent, 0); sdb_num_set (db, K_ELSE (jump), 1, 0); if (jump <= bb->addr) { blocktype = "while"; } else { blocktype = "else"; } r_cons_printf ("\n%s {", indentstr); indent++; } } } else { ut64 addr = sdb_array_pop_num (db, "indent", NULL); if (addr == UT64_MAX) { //r_cons_printf ("\nbreak\n"); break; } bb = r_anal_bb_from_offset (core->anal, addr); nindent = sdb_num_get (db, K_INDENT (addr), NULL); if (indent > nindent) { int i; for (i = indent; i != nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s}", indentstr); } } if (nindent != indent) { r_cons_printf ("\n%s} else {\n", indentstr); } indent = nindent; } } //n_bb --; } while (n_bb > 0); r_cons_printf ("\n}\n"); r_config_restore (hc); r_config_hold_free (hc); sdb_free (db); return true; }
static bool objc_find_refs(RCore *core) { static const char *oldstr = NULL; RCoreObjc objc = {0}; const int objc2ClassSize = 0x28; const int objc2ClassInfoOffs = 0x20; const int objc2ClassMethSize = 0x18; const int objc2ClassBaseMethsOffs = 0x20; const int objc2ClassMethImpOffs = 0x10; objc.core = core; objc.word_size = (core->assembler->bits == 64)? 8: 4; RList *sections = r_bin_get_sections (core->bin); if (!sections) { return false; } RBinSection *s; RListIter *iter; r_list_foreach (sections, iter, s) { const char *name = s->name; if (strstr (name, "__objc_data")) { objc._data = s; } else if (strstr (name, "__objc_selrefs")) { objc._selrefs = s; } else if (strstr (name, "__objc_msgrefs")) { objc._msgrefs = s; } else if (strstr (name, "__objc_const")) { objc._const = s; } } if (!objc._const) { if (core->anal->verbose) { eprintf ("Could not find necessary objc_const section\n"); } return false; } if ((objc._selrefs || objc._msgrefs) && !(objc._data && objc._const)) { if (core->anal->verbose) { eprintf ("Could not find necessary Objective-C sections...\n"); } return false; } objc.db = sdb_new0 (); if (!objc_build_refs (&objc)) { return false; } oldstr = r_print_rowlog (core->print, "Parsing metadata in ObjC to find hidden xrefs"); r_print_rowlog_done (core->print, oldstr); int total = 0; ut64 off; for (off = 0; off < objc._data->vsize ; off += objc2ClassSize) { ut64 va = objc._data->vaddr + off; ut64 classRoVA = readQword (&objc, va + objc2ClassInfoOffs); if (isInvalid (classRoVA)) { continue; } ut64 classMethodsVA = readQword (&objc, classRoVA + objc2ClassBaseMethsOffs); if (isInvalid (classMethodsVA)) { continue; } int count = readDword (&objc, classMethodsVA + 4); classMethodsVA += 8; // advance to start of class methods array ut64 from = classMethodsVA; ut64 to = from + (objc2ClassMethSize * count); ut64 va2; for (va2 = from; va2 < to; va2 += objc2ClassMethSize) { bool isMsgRef = false; ut64 selRefVA = getRefPtr (&objc, va2, &isMsgRef); if (!selRefVA) { continue; } // # adjust pointer to beginning of message_ref struct to get xrefs if (isMsgRef) { selRefVA -= 8; } ut64 funcVA = readQword (&objc, va2 + objc2ClassMethImpOffs); RList *list = r_anal_xrefs_get (core->anal, selRefVA); RListIter *iter; RAnalRef *ref; r_list_foreach (list, iter, ref) { r_anal_xrefs_set (core->anal, ref->addr, funcVA, R_META_TYPE_CODE); total++; } } }
R_API void r_anal_pin_init(RAnal *a) { sdb_free (DB); DB = sdb_new0(); sdb_ptr_set (DB, "strlen", pin_strlen, 0); sdb_ptr_set (DB, "write", pin_write, 0); }
R_API int r_core_pseudo_code (RCore *core, const char *input) { Sdb *db; RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_NULL); int asmpseudo = r_config_get_i (core->config, "asm.pseudo"); int asmdecode = r_config_get_i (core->config, "asm.decode"); int asmlines = r_config_get_i (core->config, "asm.lines"); int asmbytes = r_config_get_i (core->config, "asm.bytes"); int asmoffset = r_config_get_i (core->config, "asm.offset"); int asmflags = r_config_get_i (core->config, "asm.flags"); int asmfcnlines = r_config_get_i (core->config, "asm.fcnlines"); int asmcomments = r_config_get_i (core->config, "asm.comments"); int asmfunctions = r_config_get_i (core->config, "asm.functions"); if (!fcn) { eprintf ("Cannot find function in 0x%08"PFMT64x"\n", core->offset); return R_FALSE; } r_config_set_i (core->config, "asm.pseudo", 1); r_config_set_i (core->config, "asm.decode", 0); r_config_set_i (core->config, "asm.lines", 0); r_config_set_i (core->config, "asm.bytes", 0); r_config_set_i (core->config, "asm.offset", 0); r_config_set_i (core->config, "asm.flags", 0); r_config_set_i (core->config, "asm.fcnlines", 0); r_config_set_i (core->config, "asm.comments", 0); r_config_set_i (core->config, "asm.functions", 0); db = sdb_new0 (); /* */ // walk all basic blocks // define depth level for each block // use it for indentation // asm.pseudo=true // asm.decode=true RAnalBlock *bb = r_list_first (fcn->bbs); char indentstr[1024]; int n_bb = r_list_length (fcn->bbs); r_cons_printf ("function %s () {", fcn->name); int indent = 1; int nindent = 1; do { #define I_TAB 4 #define K_ELSE(x) sdb_fmt(0,"else.%"PFMT64x,x) #define K_INDENT(x) sdb_fmt(0,"loc.%"PFMT64x,x) #define SET_INDENT(x) { memset (indentstr, ' ', x*I_TAB); indentstr [(x*I_TAB)-2] = 0; } if (!bb) break; r_cons_push (); char *code = r_core_cmd_str (core, sdb_fmt(0, "pDI %d @ 0x%08"PFMT64x"\n", bb->size, bb->addr)); r_cons_pop (); memset (indentstr, ' ', indent*I_TAB); indentstr [(indent*I_TAB)-2] = 0; code = r_str_prefix_all (code, indentstr); code[strlen(code)-1] = 0; // chop last newline //r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); //if (nindent != indent) { // r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); //} r_cons_printf ("\n%s loc_0x%llx:\n", indentstr, bb->addr); indentstr[(indent*I_TAB)-2] = 0; r_cons_printf ("\n%s", code); free (code); if (sdb_get (db, K_INDENT(bb->addr), 0)) { // already analyzed, go pop and continue // XXX check if cant pop //eprintf ("%s// 0x%08llx already analyzed\n", indentstr, bb->addr); ut64 addr = sdb_array_pop_num (db, "indent", NULL); if (addr==UT64_MAX) { int i; nindent = 1; for (i=indent; i!=nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s}", indentstr); } r_cons_printf ("\n%sreturn;\n", indentstr); break; } if (sdb_num_get (db, K_ELSE(bb->addr), 0)) { r_cons_printf ("\n%s} else {", indentstr); } else { r_cons_printf ("\n%s}", indentstr); } r_cons_printf ("\n%s goto loc_0x%llx", indentstr, addr); bb = r_anal_bb_from_offset (core->anal, addr); if (!bb) { eprintf ("failed block\n"); break; } //eprintf ("next is %llx\n", addr); nindent = sdb_num_get (db, K_INDENT(addr), NULL); if (indent>nindent) { int i; for (i=indent; i!=nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s}", indentstr); } } indent = nindent; } else { sdb_set (db, K_INDENT(bb->addr), "passed", 0); if (bb->jump != UT64_MAX) { int swap = 1; // TODO: determine which branch take first ut64 jump = swap? bb->jump: bb->fail; ut64 fail = swap? bb->fail: bb->jump; // if its from another function chop it! RAnalFunction *curfcn = r_anal_get_fcn_in (core->anal, jump, R_ANAL_FCN_TYPE_NULL); if (curfcn != fcn) { // chop that branch r_cons_printf ("\n // chop\n"); break; } if (sdb_get (db, K_INDENT(jump), 0)) { // already tracekd if (!sdb_get (db, K_INDENT(fail), 0)) { bb = r_anal_bb_from_offset (core->anal, fail); } } else { bb = r_anal_bb_from_offset (core->anal, jump); if (!bb) { eprintf ("failed to retrieve blcok at 0x%"PFMT64x"\n", jump); break; } if (fail != UT64_MAX) { // do not push if already pushed indent++; if (sdb_get (db, K_INDENT(bb->fail), 0)) { /* do nothing here */ eprintf ("BlockAlready 0x%"PFMT64x"\n", bb->addr); } else { // r_cons_printf (" { RADICAL %llx\n", bb->addr); sdb_array_push_num (db, "indent", fail, 0); sdb_num_set (db, K_INDENT(fail), indent, 0); sdb_num_set (db, K_ELSE(fail), 1, 0); r_cons_printf (" {"); } } else { r_cons_printf (" do"); sdb_array_push_num (db, "indent", jump, 0); sdb_num_set (db, K_INDENT(jump), indent, 0); sdb_num_set (db, K_ELSE(jump), 1, 0); r_cons_printf (" {"); indent++; } } } else { ut64 addr = sdb_array_pop_num (db, "indent", NULL); if (addr==UT64_MAX) { r_cons_printf ("\nbreak\n"); break; } bb = r_anal_bb_from_offset (core->anal, addr); nindent = sdb_num_get (db, K_INDENT(addr), NULL); if (indent>nindent) { int i; for (i=indent; i!=nindent; i--) { SET_INDENT (i); r_cons_printf ("\n%s}", indentstr); } } if (nindent != indent) { r_cons_printf ("\n%s} else {\n", indentstr); } indent = nindent; } } //n_bb --; } while (n_bb>0); r_cons_printf ("}\n"); r_cons_flush (); r_config_set_i (core->config, "asm.pseudo", asmpseudo); r_config_set_i (core->config, "asm.decode", asmdecode); r_config_set_i (core->config, "asm.lines", asmlines); r_config_set_i (core->config, "asm.bytes", asmbytes); r_config_set_i (core->config, "asm.offset", asmoffset); r_config_set_i (core->config, "asm.flags", asmflags); r_config_set_i (core->config, "asm.fcnlines", asmfcnlines); r_config_set_i (core->config, "asm.comments", asmcomments); r_config_set_i (core->config, "asm.functions", asmfunctions); sdb_free (db); return R_TRUE; }