mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-28 23:50:40 +00:00
Refactoring function r_type_func_guess
This commit is contained in:
parent
78dc2b5b5f
commit
8ad2d817c2
@ -580,86 +580,103 @@ R_API const char *r_type_func_args_name(Sdb *TDB, R_NONNULL const char *func_nam
|
||||
|
||||
#define MIN_MATCH_LEN 4
|
||||
|
||||
static inline bool is_function(const char *name) {
|
||||
return name && !strcmp("func", name);
|
||||
}
|
||||
|
||||
static R_OWN char *type_func_try_guess(Sdb *TDB, R_NONNULL char *name) {
|
||||
const char *res;
|
||||
if (r_str_nlen (name, MIN_MATCH_LEN) < MIN_MATCH_LEN) {
|
||||
if (strlen(name) < MIN_MATCH_LEN) {
|
||||
return NULL;
|
||||
}
|
||||
if ((res = sdb_const_get (TDB, name, NULL))) {
|
||||
bool is_func = res && !strcmp ("func", res);
|
||||
if (is_func) {
|
||||
return strdup (name);
|
||||
}
|
||||
|
||||
const char *res = sdb_const_get(TDB, name, NULL);
|
||||
if (is_function(res)) {
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool is_auto_named(char *func_name, size_t slen) {
|
||||
return slen > 4 && (r_str_startswith (func_name, "fcn.") || r_str_startswith (func_name, "loc."));
|
||||
}
|
||||
|
||||
static inline bool has_r_prefixes(char *func_name, int offset, size_t slen) {
|
||||
return slen > 4 && (offset + 3 < slen) && func_name[offset + 3] == '.';
|
||||
}
|
||||
|
||||
static char *strip_r_prefixes(char *func_name, size_t slen) {
|
||||
// strip r2 prefixes (sym, sym.imp, etc')
|
||||
int offset = 0;
|
||||
|
||||
while (has_r_prefixes(func_name, offset, slen)) {
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
return func_name + offset;
|
||||
}
|
||||
|
||||
static char *strip_common_prefixes_stdlib(char *func_name) {
|
||||
// strip common prefixes from standard lib functions
|
||||
if (r_str_startswith (func_name, "__isoc99_")) {
|
||||
func_name += 9;
|
||||
} else if (r_str_startswith (func_name, "__libc_") && !strstr(func_name, "_main")) {
|
||||
func_name += 7;
|
||||
} else if (r_str_startswith (func_name, "__GI_")) {
|
||||
func_name += 5;
|
||||
}
|
||||
|
||||
return func_name;
|
||||
}
|
||||
|
||||
static char *strip_dll_prefix(char *func_name) {
|
||||
char *tmp = strstr(func_name, "dll_");
|
||||
if (tmp) {
|
||||
return tmp + 3;
|
||||
}
|
||||
|
||||
return func_name;
|
||||
}
|
||||
|
||||
static void clean_function_name(char *func_name) {
|
||||
char *last = (char *)r_str_lchr (func_name, '_');
|
||||
if (!last || !r_str_isnumber(last + 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*last = '\0';
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// - symbol names are long and noisy, some of them might not be matched due
|
||||
// to additional information added around name
|
||||
R_API R_OWN char *r_type_func_guess(Sdb *TDB, R_NONNULL char *func_name) {
|
||||
int offset = 0;
|
||||
char *str = func_name;
|
||||
char *result = NULL;
|
||||
char *first;
|
||||
r_return_val_if_fail (TDB, false);
|
||||
r_return_val_if_fail (func_name, false);
|
||||
|
||||
size_t slen = strlen (str);
|
||||
if (slen < MIN_MATCH_LEN) {
|
||||
if (slen < MIN_MATCH_LEN || is_auto_named(str, slen)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (slen > 4) { // were name-matching so ignore autonamed
|
||||
if (!strncmp (str, "fcn.", 4) || !strncmp (str, "loc.", 4)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// strip r2 prefixes (sym, sym.imp, etc')
|
||||
while (slen > 4 && (offset + 3 < slen) && str[offset + 3] == '.') {
|
||||
offset += 4;
|
||||
}
|
||||
str += offset;
|
||||
// strip common prefixes from standard lib functions
|
||||
if (!strncmp (str, "__isoc99_", 9)) {
|
||||
str += 9;
|
||||
} else if (!strncmp (str, "__libc_", 7) && !strstr(str,"_main")) {
|
||||
str += 7;
|
||||
} else if (!strncmp (str, "__GI_", 5)) {
|
||||
str += 5;
|
||||
}
|
||||
str = strip_r_prefixes(str, slen);
|
||||
str = strip_common_prefixes_stdlib(str);
|
||||
str = strip_dll_prefix(str);
|
||||
|
||||
if ((result = type_func_try_guess (TDB, str))) {
|
||||
return result;
|
||||
}
|
||||
|
||||
str = strdup (str);
|
||||
clean_function_name(str);
|
||||
|
||||
if (*str == '_' && (result = type_func_try_guess (TDB, str + 1))) {
|
||||
free (str);
|
||||
return result;
|
||||
}
|
||||
str = strdup (str);
|
||||
// Remove func-number from module_func-number
|
||||
// sym._ExitProcess_4 ==> ExitProcess
|
||||
char *l = (char *)r_str_lchr (str, '_');
|
||||
if (l) {
|
||||
char *tmp = l + 1;
|
||||
char *first = strchr (str, '_');
|
||||
while (tmp && IS_DIGIT (*tmp)) {
|
||||
tmp++;
|
||||
}
|
||||
if (tmp && first && !*tmp) {
|
||||
*l = '\0';
|
||||
if (*str == '_' && (result = type_func_try_guess (TDB, str + 1))) {
|
||||
free (str);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
// some names are in format module.dll_function_number, try to remove those
|
||||
// also try module.dll_function and function_number
|
||||
if ((first = strstr (str, "dll_"))) {
|
||||
result = type_func_try_guess (TDB, first + 4);
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
|
||||
free (str);
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user