static int bbAdd(Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) { ut64 block_start = getCrossingBlock (db, "bbs", from, to); int add = 1; if (block_start == UT64_MAX) { // add = 1; } else if (block_start == from) { // check if size is the same, add = 0; } else { /* from = start address of new basic block to = end address of new basic block jump = destination basic block fail = fallback jump of basic block addr = previous closer basic block start address addr_end = previous closer basic block start address */ // found a possible block if (from > block_start) { // from inside // RESIZE this sdb_num_set (db, Fbb(block_start), from, 0); sdb_num_set (db, FbbTo(block_start), from, 0); sdb_array_set_num (db, FbbTo(block_start), 0, from, 0); sdb_array_set_num (db, FbbTo(block_start), 1, UT64_MAX, 0); } else { // < the current runs into a known block to = block_start; jump = block_start; fail = UT64_MAX; } } if (add) { sdb_array_add_num (db, "bbs", from, 0); sdb_num_set (db, Fbb(from), to, 0); sdb_array_set_num (db, FbbTo(from), 0, jump, 0); sdb_array_set_num (db, FbbTo(from), 1, fail, 0); sdb_num_min (db, "min", from, 0); sdb_num_max (db, "max", to, 0); } return 0; }
static int bbAdd (Sdb *db, ut64 from, ut64 to, ut64 jump, ut64 fail) { ut64 addr_end, addr = sdb_array_get_closer_num (db, "bbs", from); int add = 1; if (addr == UT64_MAX) { // add = 1; } else if (addr == from) { // check if size is the same, eprintf ("basic block already analyzed\n"); add = 0; } else { /* from = start address of new basic block to = end address of new basic block jump = destination basic block fail = fallback jump of basic block addr = previous closer basic block start address addr_end = previous closer basic block start address */ addr_end = sdb_num_get (db, Fbb(addr), NULL); if (addr_end) { if (from >= addr && from < addr_end) { eprintf ("OVERLAPS MUST SPLIT\n"); /* reduce current basic block to from */ eprintf ("Shrink basic block 0x%08"PFMT64x" to %d\n", addr, (int)(from-addr)); sdb_num_set (db, Fbb(addr), addr + from-addr, 0); sdb_num_set (db, FbbTo(addr), from, 0); //to = addr_end; // ??? } } } if (add) { sdb_array_add_num (db, "bbs", from, 0); sdb_num_set (db, Fbb(from), to, 0); if (jump != UT64_MAX) sdb_array_set_num (db, FbbTo(from), 0, jump, 0); if (fail != UT64_MAX) sdb_array_set_num (db, FbbTo(from), 1, fail, 0); sdb_num_min (db, "min", from, 0); sdb_num_max (db, "max", to, 0); } return 0; }
static int trace_hook_reg_write(RAnalEsil *esil, const char *name, ut64 val) { int ret = 0; eprintf ("[ESIL] REG WRITE %s 0x%08"PFMT64x"\n", name, val); sdb_array_add (DB, KEY ("reg.write"), name, 0); sdb_num_set (DB, KEYREG ("reg.write", name), val, 0); if (ocbs.hook_reg_write) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_reg_write (esil, name, val); esil->cb = cbs; } return ret; }
void addTarget(RCore *core, RStack *stack, Sdb *db, ut64 addr) { if (!sdb_num_get (db, Fhandled(addr), NULL)) { ut64* value = (ut64*) malloc (1 * sizeof(ut64)); if (!value) { eprintf ("Failed to allocate memory for address stack\n"); return; } *value = addr; if (!r_stack_push (stack, (void*)value)) { eprintf ("Failed to push address on stack\n"); free (value); return; } sdb_num_set (db, Fhandled(addr), 1, 0); } }
R_API void r_bin_filter_sym(RBinFile *bf, Sdb *db, ut64 vaddr, RBinSymbol *sym) { if (!db || !sym || !sym->name) { return; } char *name = sym->name; // if (!strncmp (sym->name, "imp.", 4)) { // demangle symbol name depending on the language specs if any if (bf && bf->o && bf->o->lang) { const char *lang = r_bin_lang_tostring (bf->o->lang); char *dn = r_bin_demangle (bf, lang, sym->name, sym->vaddr); if (dn && *dn) { sym->dname = dn; // XXX this is wrong but is required for this test to pass // pmb:new pancake$ bin/r2r.js db/formats/mangling/swift sym->name = dn; // extract class information from demangled symbol name char *p = strchr (dn, '.'); if (p) { if (IS_UPPER (*dn)) { sym->classname = strdup (dn); sym->classname[p - dn] = 0; } else if (IS_UPPER (p[1])) { sym->classname = strdup (p + 1); p = strchr (sym->classname, '.'); if (p) { *p = 0; } } } } } // XXX this is very slow, must be optimized const char *uname = sdb_fmt ("%" PFMT64x ".%s", vaddr, name); ut32 vhash = sdb_hash (uname); // vaddr hash - unique ut32 hash = sdb_hash (name); // 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; } sdb_num_set (db, sdb_fmt ("%x", vhash), 1, 0); sym->dup_count = count - 1; }
static int trace_hook_reg_read(RAnalEsil *esil, const char *name, ut64 *res) { int ret = 0; ut64 val = 0LL; if (*name=='0') { eprintf ("Register not found in profile\n"); return 0; } if (esil->cb.reg_read) { (void)esil->cb.reg_read (esil, name, &val); } eprintf ("[ESIL] REG READ %s 0x%08"PFMT64x"\n", name, val); sdb_array_add (DB, KEY ("reg.read"), name, 0); sdb_num_set (DB, KEYREG ("reg.read", name), val, 0); if (ocbs.hook_reg_read) { RAnalEsilCallbacks cbs = esil->cb; esil->cb = ocbs; ret = ocbs.hook_reg_read (esil, name, res); esil->cb = cbs; } return ret; }
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 int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) { int relocations_size, dos_file_size; if (!(bin->dos_header = R_NEW0 (MZ_image_dos_header))) { r_sys_perror ("malloc (MZ_image_dos_header)"); return false; } // TODO: read field by field to avoid endian and alignment issues if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header, sizeof (*bin->dos_header)) == -1) { eprintf ("Error: read (MZ_image_dos_header)\n"); return false; } if (bin->dos_header->blocks_in_file < 1) { return false; } dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \ bin->dos_header->bytes_in_last_block; bin->dos_file_size = dos_file_size; if (dos_file_size > bin->size) { return false; } relocations_size = bin->dos_header->num_relocs * sizeof (MZ_image_relocation_entry); if ((bin->dos_header->reloc_table_offset + relocations_size) > bin->size) { return false; } sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0); sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0); sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0); sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0); sdb_num_set (bin->kv, "mz.overlay_number", bin->dos_header->overlay_number, 0); sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0); sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww" " signature bytes_in_last_block blocks_in_file num_relocs " " header_paragraphs min_extra_paragraphs max_extra_paragraphs " " ss sp checksum ip cs reloc_table_offset overlay_number ", 0); bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \ sizeof (MZ_image_dos_header); if (bin->dos_extended_header_size > 0) { if (!(bin->dos_extended_header = malloc (bin->dos_extended_header_size))) { r_sys_perror ("malloc (dos extended header)"); return false; } if (r_buf_read_at (bin->b, sizeof (MZ_image_dos_header), (ut8*)bin->dos_extended_header, bin->dos_extended_header_size) == -1) { eprintf ("Error: read (dos extended header)\n"); return false; } } if (relocations_size > 0) { if (!(bin->relocation_entries = malloc (relocations_size))) { r_sys_perror ("malloc (dos relocation entries)"); return false; } if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset, (ut8*)bin->relocation_entries, relocations_size) == -1) { eprintf ("Error: read (dos relocation entries)\n"); R_FREE (bin->relocation_entries); return false; } } return true; }
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; }
static int r_bin_mz_init_hdr(struct r_bin_mz_obj_t* bin) { int relocations_size, dos_file_size; if (!(bin->dos_header = malloc (sizeof(MZ_image_dos_header)))) { r_sys_perror ("malloc (MZ_image_dos_header)"); return R_FALSE; } if (r_buf_read_at (bin->b, 0, (ut8*)bin->dos_header, sizeof(*bin->dos_header)) == -1) { eprintf ("Error: read (MZ_image_dos_header)\n"); return R_FALSE; } if (bin->dos_header->blocks_in_file < 1) return R_FALSE; dos_file_size = ((bin->dos_header->blocks_in_file - 1) << 9) + \ bin->dos_header->bytes_in_last_block; bin->dos_file_size = dos_file_size; if (dos_file_size > bin->size) return R_FALSE; relocations_size = bin->dos_header->num_relocs * \ sizeof(MZ_image_relocation_entry); /* Check if relocation table doesn't exceed dos binary size */ if ((bin->dos_header->reloc_table_offset + relocations_size) > \ dos_file_size) return R_FALSE; sdb_num_set (bin->kv, "mz.initial.cs", bin->dos_header->cs, 0); sdb_num_set (bin->kv, "mz.initial.ip", bin->dos_header->ip, 0); sdb_num_set (bin->kv, "mz.initial.ss", bin->dos_header->ss, 0); sdb_num_set (bin->kv, "mz.initial.sp", bin->dos_header->sp, 0); sdb_num_set (bin->kv, "mz.overlay_number", bin->dos_header->overlay_number, 0); sdb_num_set (bin->kv, "mz.dos_header.offset", 0, 0); sdb_set (bin->kv, "mz.dos_header.format", "[2]zwwwwwwwwwwwww" " signature bytes_in_last_block blocks_in_file num_relocs " " header_paragraphs min_extra_paragraphs max_extra_paragraphs " " ss sp checksum ip cs reloc_table_offset overlay_number ", 0); bin->dos_extended_header_size = bin->dos_header->reloc_table_offset - \ sizeof(MZ_image_dos_header); if (bin->dos_extended_header_size > 0) { if (!(bin->dos_extended_header = \ malloc (bin->dos_extended_header_size))) { r_sys_perror ("malloc (dos extended header)"); return R_FALSE; } if (r_buf_read_at (bin->b, sizeof(MZ_image_dos_header), (ut8*)bin->dos_extended_header, bin->dos_extended_header_size) == -1) { eprintf ("Error: read (dos extended header)\n"); return R_FALSE; } } if (relocations_size > 0) { if (!(bin->relocation_entries = malloc (relocations_size))) { r_sys_perror ("malloc (dos relocation entries)"); return R_FALSE; } if (r_buf_read_at (bin->b, bin->dos_header->reloc_table_offset, (ut8*)bin->relocation_entries, relocations_size) == -1) { eprintf ("Error: read (dos relocation entries)\n"); return R_FALSE; } } return R_TRUE; }