Add one similarity against all functions of another binary (#4584)
This commit is contained in:
parent
c02c0b744e
commit
819812c430
3 changed files with 76 additions and 7 deletions
|
|
@ -513,6 +513,40 @@ static void *analysis_match_functions(SharedContext *shared) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void *analysis_match_one_function(SharedContext *shared) {
|
||||
RzAnalysisFunction *fcn_a = NULL, *fcn_b = NULL;
|
||||
RzAnalysisMatchPair *pair = NULL;
|
||||
ut32 size_a = 0, size_b = 0;
|
||||
ut8 *buf_a = NULL, *buf_b = NULL;
|
||||
|
||||
fcn_b = rz_list_first(shared->list_b);
|
||||
if (!shared_context_alloc_a(shared, fcn_b, &buf_b, &size_b)) {
|
||||
RZ_LOG_ERROR("analysis_match: cannot allocate buffer for function %s (B)\n", fcn_b->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (rz_atomic_bool_get(shared->loop) && (fcn_a = rz_th_queue_pop(shared->queue, false))) {
|
||||
if (!shared_context_alloc_b(shared, fcn_a, &buf_a, &size_a)) {
|
||||
RZ_LOG_ERROR("analysis_match: cannot allocate buffer for function %s (A)\n", fcn_a->name);
|
||||
free(buf_b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
double similarity = calculate_similarity(buf_a, size_a, buf_b, size_b);
|
||||
free(buf_a);
|
||||
|
||||
if (!(pair = match_pair_new(fcn_a, fcn_b, similarity))) {
|
||||
RZ_LOG_ERROR("analysis_match: cannot allocate match pair\n");
|
||||
free(buf_b);
|
||||
return NULL;
|
||||
}
|
||||
rz_th_queue_push(shared->matches, pair, true);
|
||||
}
|
||||
|
||||
free(buf_b);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Finds matching functions of 2 given lists of functions using the same RzAnalysis core
|
||||
*
|
||||
|
|
@ -524,5 +558,8 @@ static void *analysis_match_functions(SharedContext *shared) {
|
|||
*/
|
||||
RZ_API RZ_OWN RzAnalysisMatchResult *rz_analysis_match_functions(RzList /*<RzAnalysisFunction *>*/ *list_a, RzList /*<RzAnalysisFunction *>*/ *list_b, RZ_NONNULL RzAnalysisMatchOpt *opt) {
|
||||
rz_return_val_if_fail(opt && opt->analysis_a && opt->analysis_b && list_a && list_b, NULL);
|
||||
if (rz_list_length(list_a) == 1) {
|
||||
return analysis_match_result_new(opt, list_b, list_a, (RzThreadFunction)analysis_match_one_function, (AllocateBuffer)function_data_new);
|
||||
}
|
||||
return analysis_match_result_new(opt, list_a, list_b, (RzThreadFunction)analysis_match_functions, (AllocateBuffer)function_data_new);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ static void rz_diff_show_help(bool usage_only) {
|
|||
"", "", " bytes | compare raw bytes in the files (only for small files)",
|
||||
"", "", " lines | compare text files",
|
||||
"", "", " functions | compare functions found in the files",
|
||||
"", "", " | optional -0 <fcn name|offset> to compare only one function",
|
||||
"", "", " classes | compare classes found in the files",
|
||||
"", "", " command | compare command output returned when executed in both files",
|
||||
"", "", " | require -0 <cmd> and -1 <cmd> is optional",
|
||||
|
|
@ -365,9 +366,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct
|
|||
} else if (!strcmp(type, "lines")) {
|
||||
rz_diff_ctx_set_type(ctx, DIFF_TYPE_LINES);
|
||||
} else if (!strcmp(type, "functions")) {
|
||||
if (ctx->input_a) {
|
||||
rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' does not support -0.\n", type);
|
||||
} else if (ctx->input_b) {
|
||||
if (ctx->input_b) {
|
||||
rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "option -t '%s' does not support -1.\n", type);
|
||||
}
|
||||
ctx->option = DIFF_OPT_GRAPH;
|
||||
|
|
@ -2072,7 +2071,7 @@ static int comparePairFunctions(const RzAnalysisMatchPair *ma, const RzAnalysisM
|
|||
* Then the scores are shown in a table (when in quiet mode, the table
|
||||
* is headerless)
|
||||
* */
|
||||
static void core_diff_show(RzCore *core_a, RzCore *core_b, DiffMode mode, bool verbose) {
|
||||
static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, DiffMode mode, bool verbose) {
|
||||
rz_return_if_fail(core_a && core_b);
|
||||
|
||||
char *output = NULL;
|
||||
|
|
@ -2085,8 +2084,22 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, DiffMode mode, bool v
|
|||
RzAnalysisFunction *fcn_a = NULL, *fcn_b = NULL;
|
||||
RzListIter *iter = NULL;
|
||||
bool color = false, no_name = false;
|
||||
|
||||
fcns_a = rz_list_clone(rz_analysis_function_list(core_a->analysis));
|
||||
if (RZ_STR_ISEMPTY(addr_a)) {
|
||||
fcns_a = rz_list_clone(rz_analysis_function_list(core_a->analysis));
|
||||
} else {
|
||||
fcns_a = rz_list_new();
|
||||
if (!fcns_a) {
|
||||
RZ_LOG_ERROR("rz-diff: failed to create new list.\n");
|
||||
goto fail;
|
||||
}
|
||||
ut64 addr = rz_num_get(core_a->num, addr_a);
|
||||
RzAnalysisFunction *fcn = rz_analysis_get_function_at(core_a->analysis, addr);
|
||||
if (!fcn) {
|
||||
RZ_LOG_ERROR("rz-diff: failed to find %s in file0.\n", addr_a);
|
||||
goto fail;
|
||||
}
|
||||
rz_list_append(fcns_a, fcn);
|
||||
}
|
||||
if (rz_list_empty(fcns_a)) {
|
||||
RZ_LOG_ERROR("rz-diff: No functions found in file0.\n");
|
||||
goto fail;
|
||||
|
|
@ -2296,7 +2309,7 @@ static bool rz_diff_graphs_files(DiffContext *ctx) {
|
|||
if (ctx->verbose) {
|
||||
fprintf(stderr, "rz-diff: start diffing.\n");
|
||||
}
|
||||
core_diff_show(a->core, b->core, ctx->mode, ctx->verbose);
|
||||
core_diff_show(a->core, b->core, ctx->input_a, ctx->mode, ctx->verbose);
|
||||
}
|
||||
|
||||
success = true;
|
||||
|
|
|
|||
|
|
@ -980,3 +980,22 @@ EXPECT=<<EOF
|
|||
`-------------------------------------------------------------------------------------------------'
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=rz-diff functions comparison against only one function
|
||||
FILE==
|
||||
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions -0 test.00401ae0 bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
EXPECT=<<EOF
|
||||
.-------------------------------------------------------------------------------------------------.
|
||||
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
|
||||
)-------------------------------------------------------------------------------------------------(
|
||||
| test.00401470 | 41 | 0x00401470 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004019a0 | 137 | 0x004019a0 | UNLIKE | 0.1228 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401a30 | 162 | 0x00401a30 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401af0 | 228 | 0x00401af0 | PARTIAL | 0.964912 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401bf0 | 2728 | 0x00401bf0 | UNLIKE | 0.0433 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402740 | 425 | 0x00402740 | UNLIKE | 0.1106 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004029b0 | 50 | 0x004029b0 | UNLIKE | 0.0702 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402e30 | 204 | 0x00402e30 | UNLIKE | 0.1140 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
`-------------------------------------------------------------------------------------------------'
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue