diff --git a/TODO b/TODO index ea067712d6..95137dc5c0 100644 --- a/TODO +++ b/TODO @@ -22,6 +22,7 @@ ====[[ 0.9 ]]==== +* Add support for classes (useful for c++, dex, objc, ...) * Implement hex:// io :D like malloc but initialized.. use malloc here? OSX diff --git a/libr/anal/fcn.c b/libr/anal/fcn.c index 54ab8c7441..15cd514792 100644 --- a/libr/anal/fcn.c +++ b/libr/anal/fcn.c @@ -44,9 +44,36 @@ R_API void r_anal_fcn_free(void *_fcn) { free (fcn); } +R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFcn *fcn, ut64 at, ut64 addr, int type) { + RAnalRef *ref; + if (!fcn || !anal) + return R_FALSE; + if (!(ref = r_anal_ref_new ())) + return R_FALSE; + ref->type = type; + ref->at = at; + ref->addr = addr; + // TODO: ensure we are not dupping xrefs + r_list_append (fcn->refs, ref); + return R_TRUE; +} + +R_API int r_anal_fcn_xref_del (RAnal *anal, RAnalFcn *fcn, ut64 at, ut64 addr, int type) { + RAnalRef *ref; + RListIter *iter; + r_list_foreach (fcn->xrefs, iter, ref) { + if ((type != -1 || type == ref->type) && + (at == 0LL || at == ref->at) && + (addr == 0LL || addr == ref->addr)) { + r_list_delete (fcn->xrefs, iter); + return R_TRUE; + } + } + return R_FALSE; +} + R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len, int reftype) { RAnalOp op; - RAnalRef *ref; char *varname; int oplen, idx = 0; if (fcn->addr == -1) @@ -98,17 +125,10 @@ R_API int r_anal_fcn(RAnal *anal, RAnalFcn *fcn, ut64 addr, ut8 *buf, ut64 len, case R_ANAL_OP_TYPE_JMP: case R_ANAL_OP_TYPE_CJMP: case R_ANAL_OP_TYPE_CALL: - /* TODO: loc's should end with jmp too? */ - if (!(ref = r_anal_ref_new ())) { - eprintf ("Error: new (ref)\n"); + if (!r_anal_fcn_xref_add (anal, fcn, op.addr, op.jump, + op.type == R_ANAL_OP_TYPE_CALL? + R_ANAL_REF_TYPE_CALL : R_ANAL_REF_TYPE_CODE)) return R_ANAL_RET_ERROR; - } - ref = R_NEW (RAnalRef); - ref->type = op.type == R_ANAL_OP_TYPE_CALL? - R_ANAL_REF_TYPE_CALL : R_ANAL_REF_TYPE_CODE; - ref->at = op.addr; - ref->addr = op.jump; - r_list_append (fcn->refs, ref); break; case R_ANAL_OP_TYPE_RET: return R_ANAL_RET_END; diff --git a/libr/bin/format/dex/dex.c b/libr/bin/format/dex/dex.c index 568bdd3653..82d5cfa254 100644 --- a/libr/bin/format/dex/dex.c +++ b/libr/bin/format/dex/dex.c @@ -3,6 +3,7 @@ #include "dex.h" char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin) { + // TODO: ripe!!! pas char *version = malloc (8); memset (version, 0, 8); memcpy (version, bin->b->buf+4, 3); @@ -17,23 +18,22 @@ struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf) { memset (bin, 0, sizeof (struct r_bin_dex_obj_t)); bin->b = buf; bin->size = buf->length; + // XXX: this is not endian safe r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t)); bin->strings = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32) + 1); - r_buf_read_at(bin->b, bin->header.strings_offset, (ut8*)bin->strings, + r_buf_read_at (bin->b, bin->header.strings_offset, (ut8*)bin->strings, bin->header.strings_size * sizeof (ut32)); bin->methods = (struct dex_method_t *) malloc (bin->header.method_size * sizeof (struct dex_method_t) + 1); - r_buf_read_at(bin->b, bin->header.method_offset, (ut8*)bin->methods, + r_buf_read_at (bin->b, bin->header.method_offset, (ut8*)bin->methods, bin->header.method_size * sizeof (struct dex_method_t)); bin->fields = (struct dex_field_t *) malloc (bin->header.fields_size * sizeof (struct dex_field_t) + 1); - r_buf_read_at(bin->b, bin->header.fields_offset, (ut8*)bin->fields, + r_buf_read_at (bin->b, bin->header.fields_offset, (ut8*)bin->fields, bin->header.fields_size * sizeof (struct dex_field_t)); - - return bin; } diff --git a/libr/bin/format/java/java.c b/libr/bin/format/java/java.c index b511986f47..d8b0f68b10 100644 --- a/libr/bin/format/java/java.c +++ b/libr/bin/format/java/java.c @@ -235,7 +235,7 @@ static int javasm_init(RBinJavaObj *bin) { sz = R_BIN_JAVA_USHORT (buf, 0); bin->cp_items[i].length = sz; bin->cp_items[i].off += 3; - if (sz>=0 && szb, R_BUF_CUR, (ut8*)buf, sz); buf[sz] = '\0'; } else { @@ -341,12 +341,12 @@ static int javasm_init(RBinJavaObj *bin) { bin->methods[i].name = malloc (1024); // XXX: can null ptr here snprintf (bin->methods[i].name, 1023, "%s%s", - (get_cp (bin, R_BIN_JAVA_USHORT(buf, 2)-1))->value, - (get_cp (bin, R_BIN_JAVA_USHORT(buf, 2)))->value); + (get_cp (bin, R_BIN_JAVA_USHORT (buf, 2)-1))->value, + (get_cp (bin, R_BIN_JAVA_USHORT (buf, 2)))->value); #endif bin->midx = i; IFDBG printf(" Name Index: %d (%s)\n", bin->methods[i].name_idx, bin->methods[i].name); - bin->methods[i].descriptor_idx = R_BIN_JAVA_USHORT(buf, 4); + bin->methods[i].descriptor_idx = R_BIN_JAVA_USHORT (buf, 4); bin->methods[i].descriptor = r_str_dup (NULL, (get_cp(bin, R_BIN_JAVA_USHORT(buf, 4)-1))->value); IFDBG printf(" Descriptor Index: %d (%s)\n", bin->methods[i].descriptor_idx, bin->methods[i].descriptor); @@ -394,21 +394,29 @@ ut64 r_bin_java_get_entrypoint(RBinJavaObj* bin) { struct r_bin_java_sym_t* r_bin_java_get_symbols(RBinJavaObj* bin) { struct r_bin_java_sym_t *symbols; - int i, j, ctr = 0; + int ns, i, j, ctr = 0; if ((symbols = malloc ((bin->methods_count + 1) * sizeof(struct r_bin_java_sym_t))) == NULL) return NULL; + bin->fsym = 0; + bin->fsymsz = 0; for (i=0; i < bin->methods_count; i++) { - memcpy(symbols[ctr].name, bin->methods[i].name, R_BIN_JAVA_MAXSTR); + memcpy (symbols[ctr].name, bin->methods[i].name, R_BIN_JAVA_MAXSTR); symbols[ctr].name[R_BIN_JAVA_MAXSTR-1] = '\0'; for (j=0; j < bin->methods[i].attr_count; j++) if (bin->methods[i].attributes[j].type == R_BIN_JAVA_TYPE_CODE) { symbols[ctr].offset = (ut64)bin->methods[i].attributes->info.code.code_offset; symbols[ctr].size = bin->methods[i].attributes->info.code.code_length; symbols[ctr].last = 0; + if (bin->fsym == 0 || symbols[ctr].offsetfsym) + bin->fsym = symbols[ctr].offset; + ns = symbols[ctr].offset + symbols[ctr].size; + if (ns>bin->fsymsz) + bin->fsymsz = ns; ctr++; } } + bin->fsymsz -= bin->fsym; symbols[ctr].last = 1; return symbols; } diff --git a/libr/bin/format/java/java.h b/libr/bin/format/java/java.h index 68d2f151a3..aa238c8f37 100644 --- a/libr/bin/format/java/java.h +++ b/libr/bin/format/java/java.h @@ -89,11 +89,13 @@ typedef struct r_bin_java_obj_t { const char* file; struct r_buf_t*b; int midx; + int fsym; + int fsymsz; } RBinJavaObj; struct r_bin_java_sym_t { char name[R_BIN_JAVA_MAXSTR]; - ut64 offset; + ut64 offset; // XXX: ut64 is too much ut64 size; int last; }; diff --git a/libr/bin/p/bin_dex.c b/libr/bin/p/bin_dex.c index 707abc551f..72976aac80 100644 --- a/libr/bin/p/bin_dex.c +++ b/libr/bin/p/bin_dex.c @@ -30,9 +30,8 @@ static RBinInfo * info(RBinArch *arch) { RBinInfo *ret = NULL; char *version; - if (!(ret = R_NEW (RBinInfo))) + if (!(ret = R_NEW0 (RBinInfo))) return NULL; - memset (ret, '\0', sizeof (RBinInfo)); strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS); strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ret->type, "DEX CLASS", R_BIN_SIZEOF_STRINGS); @@ -75,7 +74,7 @@ static RList* strings (RBinArch *arch) { ptr->size = len; ptr->ordinal = i+1; r_list_append (ret, ptr); - } else eprintf ("dex_read_uleb128: invalid read\n"); + } //else eprintf ("dex_read_uleb128: invalid read\n"); } return ret; } @@ -84,7 +83,7 @@ static RList* methods (RBinArch *arch) { RList *ret = NULL; struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj; int i, j, len; - char buf[6]; + char *name, buf[6]; RBinSymbol *ptr; if (!(ret = r_list_new ())) @@ -94,11 +93,19 @@ static RList* methods (RBinArch *arch) { if (!(ptr = R_NEW (RBinSymbol))) break; r_buf_read_at (bin->b, bin->strings[bin->methods[i].name_id], (ut8*)&buf, 6); - strncpy (ptr->name, "method.", 7); len = dex_read_uleb128 (buf); - r_buf_read_at(bin->b, bin->strings[bin->methods[i].name_id]+ - dex_uleb128_len (buf), (ut8*)&ptr->name+7, len); - ptr->name[(int) len+7]='\0'; + + name = malloc (len); + if (!name) { + eprintf ("error malloc string length %d\n", len); + break; + } + r_buf_read_at (bin->b, bin->strings[bin->methods[i].name_id]+ + dex_uleb128_len (buf), (ut8*)name, len); + snprintf (ptr->name, sizeof (ptr->name), "method.%d.%s", + bin->methods[i].class_id, name); + free (name); + strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS); @@ -108,16 +115,24 @@ static RList* methods (RBinArch *arch) { ptr->ordinal = i+1; r_list_append (ret, ptr); } - j=i; + j = i; for (i = 0; iheader.fields_size; i++) { if (!(ptr = R_NEW (RBinSymbol))) break; r_buf_read_at (bin->b, bin->strings[bin->fields[i].name_id], (ut8*)&buf, 6); - strncpy (ptr->name, "field.", 6); + len = dex_read_uleb128 (buf); - r_buf_read_at(bin->b, bin->strings[bin->fields[i].name_id]+ - dex_uleb128_len (buf), (ut8*)&ptr->name+6, len); - ptr->name[(int) len+6]='\0'; + name = malloc (len); + if (!name) { + eprintf ("error malloc string length %d\n", len); + break; + } + r_buf_read_at (bin->b, bin->strings[bin->fields[i].name_id]+ + dex_uleb128_len (buf), (ut8*)name, len); + snprintf (ptr->name, sizeof (ptr->name), "field.%d.%s", + bin->fields[i].class_id, name); + free (name); + strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS); @@ -141,17 +156,33 @@ static RList* classes (RBinArch *arch) { return NULL; ret->free = free; for (i = 0; i < bin->header.class_size; i++) { - r_buf_read_at (bin->b, (ut64) bin->header.class_offset, (ut8*)&entry, + r_buf_read_at (bin->b, (ut64) bin->header.class_offset + + (sizeof (struct dex_class_t)*i), (ut8*)&entry, sizeof (struct dex_class_t)); -#if 0 - eprintf ("ut32 class_id = %08x;\n", entry.class_id); - eprintf ("ut32 access_flags = %08x;\n", entry.access_flags); - eprintf ("ut32 super_class = %08x;\n", entry.super_class); - eprintf ("ut32 interfaces_offset = %08x;\n", entry.interfaces_offset); - eprintf ("ut32 source_file = %08x;\n", entry.source_file); - eprintf ("ut32 anotations_offset = %08x;\n", entry.anotations_offset); - eprintf ("ut32 class_data_offset = %08x;\n", entry.class_data_offset); - eprintf ("ut32 static_values_offset = %08x;\n\n", entry.static_values_offset); + // r_list_append + // TODO: implement sections.. each section specifies a class boundary +#if 1 + //eprintf ("ut32 class_id = %d;\n", entry.class_id); +{ + int len = 100; + char *name = malloc (len); + if (!name) { + eprintf ("error malloc string length %d\n", len); + break; + } + r_buf_read_at (bin->b, bin->strings[entry.source_file], + (ut8*)name, len); + //snprintf (ptr->name, sizeof (ptr->name), "field.%s.%d", name, i); + eprintf ("class.%s=%d\n", name[0]==12?name+1:name, entry.class_id); + free (name); +} + eprintf ("# access_flags = %x;\n", entry.access_flags); + eprintf ("# super_class = %d;\n", entry.super_class); + eprintf ("# interfaces_offset = %08x;\n", entry.interfaces_offset); + //eprintf ("ut32 source_file = %08x;\n", entry.source_file); + eprintf ("# anotations_offset = %08x;\n", entry.anotations_offset); + eprintf ("# class_data_offset = %08x;\n", entry.class_data_offset); + eprintf ("# static_values_offset = %08x;\n\n", entry.static_values_offset); #endif } return 0; //FIXME: This must be main offset @@ -184,6 +215,54 @@ static int getoffset (RBinArch *arch, int type, int idx) { return -1; } +static RList* sections(RBinArch *arch) { + RList *ret = NULL; + RBinSection *ptr = NULL; + struct r_bin_java_sym_t *s = NULL; + RList *ml; + RListIter *iter; + + int ns, fsymsz = 0; + int fsym = 0; + RBinSymbol *m; + ml = methods (arch); + r_list_foreach (ml, iter, m) { + if (fsym == 0 || m->offsetoffset; + ns = m->offset + m->size; + if (ns>fsymsz) + fsymsz = ns; + } + if (fsym == 0) + return NULL; + if (!(ret = r_list_new ())) + return NULL; + ret->free = free; + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "code"); + ptr->size = ptr->vsize = fsymsz; + ptr->offset = ptr->rva = fsym; + ptr->srwx = 4|1; + r_list_append (ret, ptr); + } + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "constpool"); + ptr->size = ptr->vsize = fsym; + ptr->offset = ptr->rva = 0; + ptr->srwx = 4; + r_list_append (ret, ptr); + } + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "data"); + ptr->offset = ptr->rva = fsymsz+fsym; + ptr->size = ptr->vsize = arch->buf->length - ptr->rva; + ptr->srwx = 4|2; + r_list_append (ret, ptr); + } + free (s); + return ret; +} + struct r_bin_plugin_t r_bin_plugin_dex = { .name = "dex", .desc = "dex format bin plugin", @@ -194,11 +273,11 @@ struct r_bin_plugin_t r_bin_plugin_dex = { .check = &check, .baddr = &baddr, .binsym = NULL, - .entries = &classes, - .sections = NULL, - .symbols = &methods, + .entries = classes, + .sections = sections, + .symbols = methods, .imports = NULL, - .strings = &strings, + .strings = strings, .info = &info, .fields = NULL, .libs = NULL, diff --git a/libr/bin/p/bin_elf.c b/libr/bin/p/bin_elf.c index 266d84f10d..0cb9ee7220 100644 --- a/libr/bin/p/bin_elf.c +++ b/libr/bin/p/bin_elf.c @@ -24,10 +24,14 @@ static ut64 baddr(RBinArch *arch) { static RBinAddr* binsym(RBinArch *arch, int sym) { RBinAddr *ret = NULL; switch (sym) { - case R_BIN_SYM_MAIN: - if (!(ret = R_NEW (RBinAddr))) + case R_BIN_SYM_ENTRY: + if (!(ret = R_NEW0 (RBinAddr))) + return NULL; + ret->offset = ret->rva = Elf_(r_bin_elf_get_entry_offset) (arch->bin_obj); + break; + case R_BIN_SYM_MAIN: + if (!(ret = R_NEW0 (RBinAddr))) return NULL; - memset (ret, '\0', sizeof (RBinAddr)); ret->offset = ret->rva = Elf_(r_bin_elf_get_main_offset) (arch->bin_obj); break; } diff --git a/libr/bin/p/bin_java.c b/libr/bin/p/bin_java.c index ca53bf6da7..a48543fdcf 100644 --- a/libr/bin/p/bin_java.c +++ b/libr/bin/p/bin_java.c @@ -40,27 +40,27 @@ static ut64 baddr(RBinArch *arch) { static RList* symbols(RBinArch *arch) { RList *ret = NULL; RBinSymbol *ptr = NULL; - struct r_bin_java_sym_t *symbols = NULL; + struct r_bin_java_sym_t *s = NULL; int i; if (!(ret = r_list_new ())) return NULL; ret->free = free; - if (!(symbols = r_bin_java_get_symbols ((struct r_bin_java_obj_t*)arch->bin_obj))) + if (!(s = r_bin_java_get_symbols ((struct r_bin_java_obj_t*)arch->bin_obj))) return ret; - for (i = 0; !symbols[i].last; i++) { + for (i = 0; !s[i].last; i++) { if (!(ptr = R_NEW (RBinSymbol))) break; - strncpy (ptr->name, symbols[i].name, R_BIN_SIZEOF_STRINGS); + strncpy (ptr->name, s[i].name, R_BIN_SIZEOF_STRINGS); strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS); strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS); - ptr->rva = ptr->offset = symbols[i].offset; - ptr->size = symbols[i].size; + ptr->rva = ptr->offset = s[i].offset; + ptr->size = s[i].size; ptr->ordinal = 0; r_list_append (ret, ptr); } - free (symbols); + free (s); return ret; } @@ -95,17 +95,17 @@ static RBinInfo* info(RBinArch *arch) { if (!(ret = R_NEW (RBinInfo))) return NULL; memset (ret, '\0', sizeof (RBinInfo)); - strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS); - strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS); - strncpy (ret->type, "JAVA CLASS", R_BIN_SIZEOF_STRINGS); + strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->type, "JAVA CLASS", R_BIN_SIZEOF_STRINGS-1); version = r_bin_java_get_version (arch->bin_obj); - strncpy (ret->bclass, version, R_BIN_SIZEOF_STRINGS); + strncpy (ret->bclass, version, R_BIN_SIZEOF_STRINGS-1); free (version); - strncpy (ret->rclass, "class", R_BIN_SIZEOF_STRINGS); - strncpy (ret->os, "any", R_BIN_SIZEOF_STRINGS); - strncpy (ret->subsystem, "any", R_BIN_SIZEOF_STRINGS); - strncpy (ret->machine, "Java VM", R_BIN_SIZEOF_STRINGS); - strncpy (ret->arch, "java", R_BIN_SIZEOF_STRINGS); + strncpy (ret->rclass, "class", R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->os, "any", R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->subsystem, "any", R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->machine, "Java VM", R_BIN_SIZEOF_STRINGS-1); + strncpy (ret->arch, "java", R_BIN_SIZEOF_STRINGS-1); ret->bits = 32; ret->big_endian = 0; ret->dbg_info = 4 | 8; /* LineNums | Syms */ @@ -138,16 +138,56 @@ static int retdemangle(const char *str) { static RBinAddr* binsym(RBinArch *arch, int sym) { RBinAddr *ret = NULL; switch (sym) { - case R_BIN_SYM_MAIN: - if (!(ret = R_NEW (RBinAddr))) + case R_BIN_SYM_ENTRY: + if (!(ret = R_NEW0 (RBinAddr))) + return NULL; + ret->offset = r_bin_java_get_entrypoint (arch->bin_obj); + break; + case R_BIN_SYM_MAIN: + if (!(ret = R_NEW0 (RBinAddr))) return NULL; - memset (ret, '\0', sizeof (RBinAddr)); ret->offset = ret->rva = r_bin_java_get_main (arch->bin_obj); break; } return ret; } +static RList* sections(RBinArch *arch) { + RList *ret = NULL; + RBinSection *ptr = NULL; + struct r_bin_java_sym_t *s = NULL; + RBinJavaObj *b = arch->bin_obj; + + if (!(ret = r_list_new ())) + return NULL; + ret->free = free; + if ((s = r_bin_java_get_symbols (arch->bin_obj))) { + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "code"); + ptr->size = ptr->vsize = b->fsymsz; + ptr->offset = ptr->rva = b->fsym; + ptr->srwx = 4|1; + r_list_append (ret, ptr); + } + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "constpool"); + ptr->size = ptr->vsize = b->fsym; + ptr->offset = ptr->rva = 0; + ptr->srwx = 4; + r_list_append (ret, ptr); + } + if ((ptr = R_NEW (RBinSection))) { + strcpy (ptr->name, "data"); + ptr->offset = ptr->rva = b->fsymsz+b->fsym; + ptr->size = ptr->vsize = arch->buf->length - ptr->rva; + ptr->srwx = 4|2; + r_list_append (ret, ptr); + } + free (s); + } + return ret; +} + struct r_bin_plugin_t r_bin_plugin_java = { .name = "java", .desc = "java bin plugin", @@ -159,8 +199,8 @@ struct r_bin_plugin_t r_bin_plugin_java = { .baddr = &baddr, .binsym = binsym, .entries = &entries, - .sections = NULL, - .symbols = &symbols, + .sections = sections, + .symbols = symbols, .imports = NULL, .strings = &strings, .info = &info, diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 44eea0d852..81fdff01cc 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -2329,24 +2329,66 @@ static int cmd_anal(void *data, const char *input) { switch (input[0]) { case 'x': switch (input[1]) { - case 'c': - case 'd': - case 'C': - // add meta xref - eprintf ("TODO: not yet implemented\n"); + case '\0': + case ' ': + // list xrefs from current address + { + ut64 addr = input[1]? r_num_math (core->num, input+1): core->offset; + RAnalFcn *fcn = r_anal_fcn_find (core->anal, addr, R_ANAL_FCN_TYPE_NULL); + if (fcn) { + RAnalRef *ref; + RListIter *iter; + r_list_foreach (fcn->refs, iter, ref) { + r_cons_printf ("%c 0x%08"PFMT64x" -> 0x%08"PFMT64x"\n", + ref->type, ref->at, ref->addr); + } + } else eprintf ("Cant find function\n"); + } break; - case '-': - // remove meta xref - eprintf ("TODO: not yet implemented\n"); + case 'c': // add meta xref + case 'd': + case 'C': { + char *p; + ut64 a, b; + RAnalFcn *fcn; + char *mi = strdup (input); + if (mi && mi[2]==' ' && (p=strchr (mi+3, ' '))) { + *p = 0; + a = r_num_math (core->num, mi+2); + b = r_num_math (core->num, p+1); + fcn = r_anal_fcn_find (core->anal, a, R_ANAL_FCN_TYPE_ROOT); + if (fcn) { + r_anal_fcn_xref_add (core->anal, fcn, a, b, input[1]); + } else eprintf ("Cannot add reference to non-function\n"); + } else eprintf ("Usage: ax[cCd?] [src] [dst]\n"); + free (mi); + } + break; + case '-': { + char *p; + ut64 a, b; + RAnalFcn *fcn; + char *mi = strdup (input); + if (mi && mi[2]==' ' && (p=strchr (mi+3, ' '))) { + *p = 0; + a = r_num_math (core->num, mi+2); + b = r_num_math (core->num, p+1); + fcn = r_anal_fcn_find (core->anal, a, R_ANAL_FCN_TYPE_ROOT); + if (fcn) { + r_anal_fcn_xref_del (core->anal, fcn, a, b, -1); + } else eprintf ("Cannot del reference to non-function\n"); + } else eprintf ("Usage: ax- [src] [dst]\n"); + free (mi); + } break; default: case '?': r_cons_printf ( - "Usage: ax[cCd?] [arg]\n" - " axc sym.main+0x38 sym.printf ; add code ref" - " axC sym.main sym.puts ; add call ref" - " axd sym.main str.helloworld ; add data ref" - " ax- sym.main str.helloworld ; remove reference"); + "Usage: ax[-cCd?] [src] [dst]\n" + " axc sym.main+0x38 sym.printf ; add code ref\n" + " axC sym.main sym.puts ; add call ref\n" + " axd sym.main str.helloworld ; add data ref\n" + " ax- sym.main str.helloworld ; remove reference\n"); break; } break; @@ -3981,7 +4023,7 @@ static int cmd_meta(void *data, const char *input) { r_list_foreach (core->anal->fcns, iter, f) memset (f->varsubs, 0, sizeof(f->varsubs)); } -} + } break; case '*': { diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index d5c21a0405..5c80abbd6a 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -539,6 +539,9 @@ R_API int r_meta_list(RMeta *m, int type); R_API void r_meta_item_free(void *_item); R_API RMetaItem *r_meta_item_new(int type); +R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFcn *fcn, ut64 at, ut64 addr, int type); +R_API int r_anal_fcn_xref_del (RAnal *anal, RAnalFcn *fcn, ut64 at, ut64 addr, int type); + /* plugin pointers */ extern RAnalPlugin r_anal_plugin_csr; extern RAnalPlugin r_anal_plugin_avr; diff --git a/libr/include/r_util.h b/libr/include/r_util.h index 9036168edb..25e467be25 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -256,8 +256,8 @@ R_API const ut8 *r_mem_mem (const ut8 *haystack, int hlen, const ut8 *needle, in #define r_num_abs(x) x>0?x:-x R_API void r_num_minmax_swap(ut64 *a, ut64 *b); R_API void r_num_minmax_swap_i(int *a, int *b); // XXX this can be a cpp macro :?? -R_API ut64 r_num_math(struct r_num_t *num, const char *str); -R_API ut64 r_num_get(struct r_num_t *num, const char *str); +R_API ut64 r_num_math(RNum *num, const char *str); +R_API ut64 r_num_get(RNum *num, const char *str); R_API int r_num_to_bits(char *out, ut64 num); R_API int r_num_rand(int max); R_API void r_num_irand(); diff --git a/libr/io/section.c b/libr/io/section.c index 5ce849f49b..e1fbca25a1 100644 --- a/libr/io/section.c +++ b/libr/io/section.c @@ -109,7 +109,8 @@ R_API void r_io_section_list_visual(RIO *io, ut64 seek, ut64 len) { else io->printf("-"); } - io->printf ("| 0x%08"PFMT64x" %s\n", s->offset+s->size, s->name); + io->printf ("| 0x%08"PFMT64x" %s %s\n", s->offset+s->size, + r_str_rwx_i (s->rwx), s->name); i++; } /* current seek */ @@ -119,7 +120,7 @@ R_API void r_io_section_list_visual(RIO *io, ut64 seek, ut64 len) { io->printf ( ((j*mul)+min >= seek && (j*mul)+min <= seek+len) - ?"#":"-"); + ?"^":"-"); } io->printf ("| 0x%08"PFMT64x"\n", seek+len); } diff --git a/r2-bindings/libs.mk b/r2-bindings/libs.mk index ff0f75a8c5..92eeeeecaf 100644 --- a/r2-bindings/libs.mk +++ b/r2-bindings/libs.mk @@ -1,13 +1,18 @@ -WIP=1 -ifeq (${WIP},1) -LIBS=r_util.${SOEXT} r_bp.${SOEXT} r_asm.${SOEXT} r_diff.${SOEXT} -LIBS+=r_bin.${SOEXT} r_cons.${SOEXT} r_anal.${SOEXT} r_cmd.${SOEXT} -LIBS+=r_debug.${SOEXT} r_config.${SOEXT} r_io.${SOEXT} r_syscall.${SOEXT} -LIBS+=r_search.${SOEXT} r_lib.${SOEXT} r_flags.${SOEXT} r_fs.${SOEXT} -LIBS+=r_parse.${SOEXT} r_lang.${SOEXT} r_core.${SOEXT} r_magic.${SOEXT} -else -LIBS=r_asm.${SOEXT} r_bin.${SOEXT} r_cons.${SOEXT} -LIBS+=r_debug.${SOEXT} r_syscall.${SOEXT} -LIBS+=r_search.${SOEXT} r_fs.${SOEXT} -LIBS+=r_core.${SOEXT} -endif +# essential +LIBS=r_core.${SOEXT} +LIBS+=r_bin.${SOEXT} +LIBS+=r_asm.${SOEXT} + +#WIP=1 +#ifeq (${WIP},1) +#LIBS=r_util.${SOEXT} r_bp.${SOEXT} r_asm.${SOEXT} r_diff.${SOEXT} +#LIBS+=r_bin.${SOEXT} r_cons.${SOEXT} r_anal.${SOEXT} r_cmd.${SOEXT} +#LIBS+=r_debug.${SOEXT} r_config.${SOEXT} r_io.${SOEXT} r_syscall.${SOEXT} +#LIBS+=r_search.${SOEXT} r_lib.${SOEXT} r_flags.${SOEXT} r_fs.${SOEXT} +#LIBS+=r_parse.${SOEXT} r_lang.${SOEXT} r_core.${SOEXT} r_magic.${SOEXT} +#else +#LIBS=r_asm.${SOEXT} r_bin.${SOEXT} r_cons.${SOEXT} +#LIBS+=r_debug.${SOEXT} r_syscall.${SOEXT} +#LIBS+=r_search.${SOEXT} r_fs.${SOEXT} +#LIBS+=r_core.${SOEXT} +#endif