From 6923af97efec0ef8a2063d44285fb481690dc308 Mon Sep 17 00:00:00 2001 From: satk0 <54475808+satk0@users.noreply.github.com> Date: Tue, 9 Jul 2024 20:33:10 +0000 Subject: [PATCH] Make duplicated zignatures optional via zign.dups + tests ##zignatures --- libr/anal/sign.c | 10 ++++++---- libr/core/cconfig.c | 1 + test/unit/test_sign.c | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/libr/anal/sign.c b/libr/anal/sign.c index f24a5b31935b3..95b7eeea93208 100644 --- a/libr/anal/sign.c +++ b/libr/anal/sign.c @@ -948,8 +948,10 @@ R_API int r_sign_all_functions(RAnal *a, bool merge) { const RSpace *sp = r_spaces_current (&a->zign_spaces); char *prev_name = NULL; r_cons_break_push (NULL, NULL); - RCore *core = a->coreb.core; - bool do_mangled = a->coreb.cfggeti (core, "zign.mangled"); + RCoreBind cb = a->coreb; + RCore *core = cb.core; + bool do_mangled = cb.cfggeti (core, "zign.mangled"); + bool zign_dups = cb.cfggeti (core, "zign.dups"); r_list_foreach_prev (a->fcns, iter, fcn) { if (r_cons_is_breaked ()) { break; @@ -958,14 +960,14 @@ R_API int r_sign_all_functions(RAnal *a, bool merge) { RSignItem *it = NULL; if (merge || !name_exists (a->sdb_zigns, realname, sp)) { it = item_from_func (a, fcn, realname); - } else { + } else if (zign_dups) { char *name = get_unique_name (a->sdb_zigns, fcn->name, sp); if (name) { it = item_from_func (a, fcn, name); } free (name); - free (realname); } + free (realname); if (it) { if (prev_name) { it->next = prev_name; diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index c97bd75d23741..b932bbd0ed83b 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -3869,6 +3869,7 @@ R_API int r_core_config_init(RCore *core) { SETI ("zign.maxsz", 500, "maximum zignature length"); SETI ("zign.minsz", 16, "minimum zignature length for matching"); SETI ("zign.mincc", 10, "minimum cyclomatic complexity for matching"); + SETBPREF ("zign.dups", "false", "allow duplicate zignatures"); SETBPREF ("zign.graph", "true", "use graph metrics for matching"); SETBPREF ("zign.bytes", "true", "use bytes patterns for matching"); SETBPREF ("zign.offset", "false", "use original offset for matching"); diff --git a/test/unit/test_sign.c b/test/unit/test_sign.c index 4b256353215d1..436d7b17fcfba 100644 --- a/test/unit/test_sign.c +++ b/test/unit/test_sign.c @@ -1,3 +1,4 @@ +#include #include #include @@ -116,8 +117,32 @@ static bool test_anal_sign_get_set(void) { mu_end; } +bool test_anal_sign_avoid_dup_functions(void) { + RCore *core = r_core_new (); + + RAnalFunction *fcn1 = r_anal_create_function (core->anal, "fcn1", 0x2137, 0, NULL); + RAnalBlock *first_block = r_anal_create_block (core->anal, 0x2137, 13); + r_anal_function_add_block (fcn1, first_block); + + RAnalFunction *fcn2 = r_anal_create_function (core->anal, "fcn2", 0xdeadbeef, 0, NULL); + RAnalBlock *second_block = r_anal_create_block (core->anal, 0xdeadbeef, 31); + r_anal_function_add_block (fcn2, second_block); + + r_core_cmd0 (core, "aF"); // find functions + + int count = r_sign_all_functions (core->anal, false); // "zg" + mu_assert_eq (count, 2, "Should create 2 new zignatures for the unseen functions"); + + count = r_sign_all_functions (core->anal, false); + mu_assert_eq (count, 0, "Should not create new zignatures for the same functions"); + + r_core_free (core); + mu_end; +} + int all_tests(void) { mu_run_test (test_anal_sign_get_set); + mu_run_test (test_anal_sign_avoid_dup_functions); return tests_passed != tests_run; }