From 04cbf6881980cafc0f95e7031c0674659b2e4068 Mon Sep 17 00:00:00 2001 From: pancake Date: Sun, 16 Oct 2011 13:59:05 +0200 Subject: [PATCH] * Fix segfault in elf (thanks @earada!) * Make cg and cgo work * Added r_anal_diff_setup_i() - Fixed bindings --- binr/radiff2/radiff2.c | 41 +---------------------------------- libr/anal/diff.c | 11 ++++++++-- libr/bin/format/elf/elf.c | 9 ++++++-- libr/core/cmd.c | 11 ++++++++-- libr/core/gdiff.c | 42 ++++++++++++++++++++++++++++++++++++ libr/include/r_core.h | 1 + r2-bindings/vapi/r_anal.vapi | 3 ++- 7 files changed, 71 insertions(+), 47 deletions(-) diff --git a/binr/radiff2/radiff2.c b/binr/radiff2/radiff2.c index 56a8caa6a1..b434195aeb 100644 --- a/binr/radiff2/radiff2.c +++ b/binr/radiff2/radiff2.c @@ -36,11 +36,6 @@ static int cb(RDiff *d, void *user, RDiffOp *op) { return 1; } -static void diffrow(ut64 addr, const char *name, ut64 addr2, const char *name2, const char *match, double dist) { - printf ("%30s 0x%"PFMT64x" |%8s (%f)| 0x%"PFMT64x" %s\n", - name, addr, match, dist, addr2, name2); -} - static RCore* opencore(const char *f) { RCore *c = r_core_new (); r_config_set_i (c->config, "io.va", useva); @@ -58,40 +53,6 @@ static void diff_graph(RCore *c, RCore *c2, const char *arg) { r_core_cmdf (c, "agd %s", arg); } -static void diff_bins(RCore *c, RCore *c2) { - const char *match; - RListIter *iter; - RAnalFcn *f; - RList *fcns = r_anal_get_fcns (c->anal); - r_list_foreach (fcns, iter, f) { - switch (f->type) { - case R_ANAL_FCN_TYPE_FCN: - case R_ANAL_FCN_TYPE_SYM: - switch (f->diff->type) { - case R_ANAL_DIFF_TYPE_MATCH: - match = "MATCH"; - break; - case R_ANAL_DIFF_TYPE_UNMATCH: - match = "UNMATCH"; - break; - default: - match = "NEW"; - } - diffrow (f->addr, f->name, f->diff->addr, f->diff->name, match, f->diff->dist); - break; - } - } - fcns = r_anal_get_fcns (c2->anal); - r_list_foreach (fcns, iter, f) { - switch (f->type) { - case R_ANAL_FCN_TYPE_FCN: - case R_ANAL_FCN_TYPE_SYM: - if (f->diff->type == R_ANAL_DIFF_TYPE_NULL) - diffrow (f->addr, f->name, f->diff->addr, f->diff->name, "NEW", f->diff->dist); - } - } -} - static int show_help(int line) { printf ("Usage: radiff2 [-cCdrspOv] [-g sym] [file] [file]\n"); if (!line) printf ( @@ -209,7 +170,7 @@ int main(int argc, char **argv) { r_core_gdiff (c, c2); if (mode == MODE_GRAPH) diff_graph (c, c2, addr); - else diff_bins (c, c2); + else r_core_diff_show (c, c2); return 0; } diff --git a/libr/anal/diff.c b/libr/anal/diff.c index edcaf0690d..0eab81f13c 100644 --- a/libr/anal/diff.c +++ b/libr/anal/diff.c @@ -22,13 +22,20 @@ R_API void* r_anal_diff_free(RAnalDiff *diff) { return NULL; } +/* 0-1 */ R_API void r_anal_diff_setup(RAnal *anal, int doops, double thbb, double thfcn) { - anal->diff_ops = doops; - if (thbb>=0) + if (doops>=0) anal->diff_ops = doops; anal->diff_thbb = (thbb>=0)? thbb: R_ANAL_THRESHOLDBB; anal->diff_thfcn = (thfcn>=0)? thfcn: R_ANAL_THRESHOLDFCN; } +/* 0-100 */ +R_API void r_anal_diff_setup_i(RAnal *anal, int doops, int thbb, int thfcn) { + if (doops>=0) anal->diff_ops = doops; + anal->diff_thbb = (thbb>=0)? ((double)thbb)/100: R_ANAL_THRESHOLDBB; + anal->diff_thfcn = (thfcn>=0)? ((double)thfcn)/100: R_ANAL_THRESHOLDFCN; +} + R_API int r_anal_diff_fingerprint_bb(RAnal *anal, RAnalBlock *bb) { RAnalOp *op; ut8 *buf; diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 1ed76c02ef..131d319ff6 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -210,9 +210,12 @@ static ut64 Elf_(r_bin_elf_get_section_addr)(struct Elf_(r_bin_elf_obj_t) *bin, int i; if (!bin->shdr || !bin->strtab) return -1; - for (i = 0; i < bin->ehdr.e_shnum; i++) + for (i = 0; i < bin->ehdr.e_shnum; i++) { + if (bin->shdr[i].sh_name > bin->shstrtab_section->sh_size) + continue; if (!strcmp (&bin->strtab[bin->shdr[i].sh_name], section_name)) return (ut64)bin->shdr[i].sh_addr; + } return -1; } @@ -771,7 +774,9 @@ struct r_bin_elf_section_t* Elf_(r_bin_elf_get_sections)(struct Elf_(r_bin_elf_o ret[i].size = bin->shdr[i].sh_size; ret[i].align = bin->shdr[i].sh_addralign; ret[i].flags = bin->shdr[i].sh_flags; - strncpy (ret[i].name, bin->shstrtab? + if (bin->shdr[i].sh_name > bin->shstrtab_section->sh_size) + strncpy (ret[i].name, "invalid", ELF_STRING_LENGTH); + else strncpy (ret[i].name, bin->shstrtab? &bin->shstrtab[bin->shdr[i].sh_name]: "unknown", ELF_STRING_LENGTH); ret[i].last = 0; } diff --git a/libr/core/cmd.c b/libr/core/cmd.c index d93fb97ada..cd0ea2a66c 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -1457,9 +1457,9 @@ static int cmd_cmp(void *data, const char *input) { #endif case 'g': { // XXX: this is broken + int diffops = 0; RCore *core2; char *file2 = NULL; - eprintf ("TODO: 'cg' is experimental. See radiff2 -C\n"); if (input[1]=='o') { file2 = (char*)r_str_chop_ro (input+2); r_anal_diff_setup (core->anal, R_TRUE, -1, -1); @@ -1485,8 +1485,15 @@ static int cmd_cmp(void *data, const char *input) { r_core_free (core2); return R_FALSE; } + // TODO: must replicate on core1 too + r_config_set_i (core2->config, "io.va", R_TRUE); + r_config_set_i (core2->config, "anal.split", R_TRUE); + r_anal_diff_setup (core->anal, diffops, -1, -1); + r_anal_diff_setup (core2->anal, diffops, -1, -1); + r_core_bin_load (core2, file2); r_core_gdiff (core, core2); + r_core_diff_show (core, core2); r_core_free (core2); } break; @@ -1501,7 +1508,7 @@ static int cmd_cmp(void *data, const char *input) { " cx [hexpair] Compare hexpair string\n" " cX [addr] Like 'cc' but using hexdiff output\n" " cf [file] Compare contents of file at current seek\n" - " cg [file] Graphdiff current file and [file]\n"); + " cg[o] [file] Graphdiff current file and [file]\n"); break; default: eprintf ("Usage: c[?Ddxf] [argument]\n"); diff --git a/libr/core/gdiff.c b/libr/core/gdiff.c index 83197c3b60..995311389b 100644 --- a/libr/core/gdiff.c +++ b/libr/core/gdiff.c @@ -38,3 +38,45 @@ R_API int r_core_gdiff(RCore *c, RCore *c2) { return R_TRUE; } + +/* copypasta from radiff2 */ +static void diffrow(ut64 addr, const char *name, ut64 addr2, const char *name2, const char *match, double dist) { + if (addr2 == UT64_MAX || name2 == NULL) + printf ("%20s 0x%"PFMT64x" |%8s (%f)\n", name, addr, match, dist); + else printf ("%20s 0x%"PFMT64x" |%8s (%f) | 0x%"PFMT64x" %s\n", + name, addr, match, dist, addr2, name2); +} + +R_API void r_core_diff_show(RCore *c, RCore *c2) { + const char *match; + RListIter *iter; + RAnalFcn *f; + RList *fcns = r_anal_get_fcns (c->anal); + r_list_foreach (fcns, iter, f) { + switch (f->type) { + case R_ANAL_FCN_TYPE_FCN: + case R_ANAL_FCN_TYPE_SYM: + switch (f->diff->type) { + case R_ANAL_DIFF_TYPE_MATCH: + match = "MATCH"; + break; + case R_ANAL_DIFF_TYPE_UNMATCH: + match = "UNMATCH"; + break; + default: + match = "NEW"; + } + diffrow (f->addr, f->name, f->diff->addr, f->diff->name, match, f->diff->dist); + break; + } + } + fcns = r_anal_get_fcns (c2->anal); + r_list_foreach (fcns, iter, f) { + switch (f->type) { + case R_ANAL_FCN_TYPE_FCN: + case R_ANAL_FCN_TYPE_SYM: + if (f->diff->type == R_ANAL_DIFF_TYPE_NULL) + diffrow (f->addr, f->name, f->diff->addr, f->diff->name, "NEW", f->diff->dist); + } + } +} diff --git a/libr/include/r_core.h b/libr/include/r_core.h index ff31e766f0..b7b290a9ea 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -242,6 +242,7 @@ R_API int r_core_patch (RCore *core, const char *patch); R_API void r_core_hack_help(RCore *core); R_API int r_core_hack(RCore *core, const char *op); +R_API void r_core_diff_show(RCore *c, RCore *c2); #endif diff --git a/r2-bindings/vapi/r_anal.vapi b/r2-bindings/vapi/r_anal.vapi index c4fe38fab0..26b2f42fea 100644 --- a/r2-bindings/vapi/r_anal.vapi +++ b/r2-bindings/vapi/r_anal.vapi @@ -18,6 +18,8 @@ public class RAnal { public bool set_big_endian (bool big); //public bool set_pc (uint64 addr); public RList get_fcns(); + public void diff_setup(bool doops, double thbb, double thfcn); + public void diff_setup_i(bool doops, int thbb, int thfcn); [Compact] [CCode (cname="RAnalValue")] @@ -299,6 +301,5 @@ public class RAnal { public bool cleanup (uint64 from, uint64 to); public static unowned string type_to_string(RMeta.Type type); public int list (RMeta.Type type); - public void diff_setup(bool doops, double thbb, double thfcn); } }