mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-03 20:22:38 +00:00
New 'avg' command and RAnal.global to manage global variables ##anal
* Tied to the flags and meta instances
This commit is contained in:
parent
36dd361694
commit
64225f30db
@ -36,7 +36,7 @@ OBJLIBS+=cond.o value.o cc.o class.o diff.o type.o type_pdb.o dwarf_process.o
|
||||
OBJLIBS+=hint.o anal.o data.o xrefs.o esil.o sign.o esil_plugin.o
|
||||
OBJLIBS+=esil_handler.o switch.o cycles.o esil_dfg.o esil_cfg.o
|
||||
OBJLIBS+=esil_stats.o esil_trace.o flirt.o labels.o
|
||||
OBJLIBS+=pin.o vtable.o rtti.o codemeta.o anplugs.o
|
||||
OBJLIBS+=pin.o vtable.o rtti.o codemeta.o anplugs.o global.o
|
||||
OBJLIBS+=rtti_msvc.o rtti_itanium.o jmptbl.o function.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-modules.o
|
||||
ASMOBJS+=$(LTOP)/asm/arch/xtensa/gnu/xtensa-isa.o
|
||||
|
76
libr/anal/global.c
Normal file
76
libr/anal/global.c
Normal file
@ -0,0 +1,76 @@
|
||||
/* radare - LGPL - Copyright 2021 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_util/r_print.h>
|
||||
|
||||
#define GLOBAL_FLAGSPACE "globals"
|
||||
|
||||
R_API RFlagItem *r_anal_global_get(RAnal *anal, ut64 addr) {
|
||||
RFlag *flags = anal->flb.f;
|
||||
RFlagItem *fi = r_flag_get_i (flags, addr);
|
||||
if (fi && fi->space && fi->space->name && !strcmp (fi->space->name, GLOBAL_FLAGSPACE)) {
|
||||
return fi;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API bool r_anal_global_add(RAnal *anal, ut64 addr, const char *type_name, const char *name) {
|
||||
RFlag *flags = anal->flb.f;
|
||||
char *fmtstr = r_type_format (anal->sdb_types, type_name);
|
||||
if (!fmtstr) {
|
||||
eprintf ("Unknown type\n");
|
||||
return false;
|
||||
}
|
||||
int fmtsize = r_print_format_struct_size (anal->print, fmtstr, 0, 0);
|
||||
if (fmtsize < 1) {
|
||||
fmtsize = 4;
|
||||
}
|
||||
// check if type exist
|
||||
RFlagItem *fi = r_flag_set_inspace (flags, GLOBAL_FLAGSPACE, name, addr, 1);
|
||||
if (fi) {
|
||||
r_flag_item_set_type (fi, fmtstr);
|
||||
}
|
||||
r_meta_set (anal, R_META_TYPE_FORMAT, addr, fmtsize, fmtstr);
|
||||
// implicit
|
||||
r_type_set_link (anal->sdb_types, fmtstr, addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
R_API bool r_anal_global_del(RAnal *anal, ut64 addr) {
|
||||
RFlagItem *fi = r_anal_global_get (anal, addr);
|
||||
if (fi) {
|
||||
RFlag *flags = anal->flb.f;
|
||||
r_meta_del (anal, R_META_TYPE_FORMAT, addr, 0);
|
||||
r_flag_unset (flags, fi);
|
||||
r_type_unlink (anal->sdb_types, addr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_anal_global_retype(RAnal *anal, ut64 addr, const char *new_type) {
|
||||
RFlagItem *fi = r_anal_global_get (anal, addr);
|
||||
if (fi) {
|
||||
r_flag_item_set_type (fi, new_type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API bool r_anal_global_rename(RAnal *anal, ut64 addr, const char *new_name) {
|
||||
RFlagItem *fi = r_anal_global_get (anal, addr);
|
||||
if (fi) {
|
||||
RFlag *flags = anal->flb.f;
|
||||
r_flag_rename (flags, fi, new_name);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
R_API const char *r_anal_global_get_type(RAnal *anal, ut64 addr) {
|
||||
RFlagItem *fi = r_anal_global_get (anal, addr);
|
||||
if (fi) {
|
||||
return fi->type;
|
||||
}
|
||||
return NULL;
|
||||
}
|
@ -23,6 +23,7 @@ r_anal_sources = [
|
||||
'esil_dfg.c',
|
||||
'fcn.c',
|
||||
'flirt.c',
|
||||
'global.c',
|
||||
'hint.c',
|
||||
'labels.c',
|
||||
'meta.c',
|
||||
|
@ -33,10 +33,25 @@ static const char *help_msg_a[] = {
|
||||
"ar", "[?]", "like 'dr' but for the esil vm. (registers)",
|
||||
"as", "[?] [num]", "analyze syscall using dbg.reg",
|
||||
"av", "[?] [.]", "show vtables",
|
||||
"avg", "[?] [.]", "manage global variables",
|
||||
"ax", "[?]", "manage refs/xrefs (see also afx?)",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_ap[] = {
|
||||
"Usage:", "ap[?]", "analyze prelude in current offset",
|
||||
"ap", "", "check if current offset contains a function prelude",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_avg[] = {
|
||||
"Usage:", "avg", "analyze variable global",
|
||||
"avg", "", "Use ESIL emulation to find out arguments of a call (uses 'abte')",
|
||||
"avg", " [type] [name]", "add global",
|
||||
"avg-", "", "delete global",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_aC[] = {
|
||||
"Usage:", "aC[fej] [addr-of-call]", "analyze call args",
|
||||
"aCe", "", "Use ESIL emulation to find out arguments of a call (uses 'abte')",
|
||||
@ -10732,8 +10747,40 @@ static void cmd_anal_rtti(RCore *core, const char *input) {
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_avg(RCore *core, const char* input) {
|
||||
switch (input[0]) {
|
||||
case ' ':
|
||||
if (strchr (input + 1, ' ')) {
|
||||
char *a = r_str_trim_dup (input + 1);
|
||||
char *b = strchr (a, ' ');
|
||||
if (b) {
|
||||
*b++ = 0;
|
||||
r_anal_global_add (core->anal, core->offset, a, b);
|
||||
} else {
|
||||
RFlagItem *fi = r_anal_global_get (core->anal, core->offset);
|
||||
if (fi) {
|
||||
eprintf ("type %s\n", fi->type);
|
||||
}
|
||||
}
|
||||
free (a);
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
r_anal_global_del (core->anal, core->offset);
|
||||
break;
|
||||
case '\0': // "av"
|
||||
r_core_cmd0 (core, "fs+globals;f;fs-");
|
||||
break;
|
||||
default :
|
||||
r_core_cmd_help (core, help_msg_avg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void cmd_anal_virtual_functions(RCore *core, const char* input) {
|
||||
switch (input[0]) {
|
||||
case 'g':
|
||||
cmd_avg (core, input + 1);
|
||||
break;
|
||||
case '\0': // "av"
|
||||
case '*': // "av*"
|
||||
case 'j': // "avj"
|
||||
@ -10748,8 +10795,6 @@ static void cmd_anal_virtual_functions(RCore *core, const char* input) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void cmd_anal_class_method(RCore *core, const char *input) {
|
||||
RAnalClassErr err = R_ANAL_CLASS_ERR_SUCCESS;
|
||||
char c = input[0];
|
||||
@ -11273,18 +11318,18 @@ static int cmd_anal(void *data, const char *input) {
|
||||
ut32 tbs = core->blocksize;
|
||||
switch (input[0]) {
|
||||
case 'p': // "ap"
|
||||
{
|
||||
if (input[1] == '?') {
|
||||
r_core_cmd_help (core, help_msg_ap);
|
||||
} else {
|
||||
const ut8 *prelude = (const ut8*)"\xe9\x2d"; //:fffff000";
|
||||
const int prelude_sz = 2;
|
||||
const int bufsz = 4096;
|
||||
ut8 *buf = calloc (1, bufsz);
|
||||
ut64 off = core->offset;
|
||||
if (input[1] == ' ') {
|
||||
off = r_num_math (core->num, input+1);
|
||||
r_io_read_at (core->io, off - bufsz + prelude_sz, buf, bufsz);
|
||||
} else {
|
||||
r_io_read_at (core->io, off - bufsz + prelude_sz, buf, bufsz);
|
||||
off = r_num_math (core->num, input + 1);
|
||||
}
|
||||
r_io_read_at (core->io, off - bufsz + prelude_sz, buf, bufsz);
|
||||
//const char *prelude = "\x2d\xe9\xf0\x47"; //:fffff000";
|
||||
r_mem_reverse (buf, bufsz);
|
||||
//r_print_hexdump (NULL, off, buf, bufsz, 16, -16);
|
||||
|
@ -463,6 +463,7 @@ static int print_struct_union_list_json(Sdb *TDB, SdbForeachCallback filter) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Rename to char *RAnal.type_to_c() {}
|
||||
static void print_struct_union_in_c_format(Sdb *TDB, SdbForeachCallback filter, const char *arg, bool multiline) {
|
||||
char *name = NULL;
|
||||
SdbKv *kv;
|
||||
@ -496,7 +497,7 @@ static void print_struct_union_in_c_format(Sdb *TDB, SdbForeachCallback filter,
|
||||
int arrnum = atoi (arr);
|
||||
free (arr);
|
||||
if (multiline) {
|
||||
r_cons_printf ("\t%s", val);
|
||||
r_cons_printf (" %s", val);
|
||||
if (p && p[0] != '\0') {
|
||||
r_cons_printf ("%s%s", strstr (val, " *")? "": " ", p);
|
||||
if (arrnum) {
|
||||
@ -855,7 +856,7 @@ R_API void r_core_link_stroff(RCore *core, RAnalFunction *fcn) {
|
||||
RAnalBlock *bb;
|
||||
RListIter *it;
|
||||
RAnalOp aop = {0};
|
||||
bool ioCache = r_config_get_i (core->config, "io.cache");
|
||||
bool ioCache = r_config_get_b (core->config, "io.cache");
|
||||
bool stack_set = false;
|
||||
bool resolved = false;
|
||||
const char *varpfx;
|
||||
@ -903,7 +904,7 @@ R_API void r_core_link_stroff(RCore *core, RAnalFunction *fcn) {
|
||||
r_core_cmd0 (core, "aeim");
|
||||
stack_set = true;
|
||||
}
|
||||
r_config_set_i (core->config, "io.cache", 1);
|
||||
r_config_set_b (core->config, "io.cache", true);
|
||||
r_config_set_i (core->config, "dbg.follow", 0);
|
||||
ut64 oldoff = core->offset;
|
||||
r_cons_break_push (NULL, NULL);
|
||||
@ -994,7 +995,7 @@ R_API void r_core_link_stroff(RCore *core, RAnalFunction *fcn) {
|
||||
}
|
||||
beach:
|
||||
r_core_cmd0 (core, "wc-*"); // drop cache writes
|
||||
r_config_set_i (core->config, "io.cache", ioCache);
|
||||
r_config_set_b (core->config, "io.cache", ioCache);
|
||||
r_config_set_i (core->config, "dbg.follow", dbg_follow);
|
||||
if (stack_set) {
|
||||
r_core_cmd0 (core, "aeim-");
|
||||
@ -1123,7 +1124,6 @@ static int cmd_type(void *data, const char *input) {
|
||||
SdbList *l = sdb_foreach_list_filter (TDB, stdifstruct, true);
|
||||
SdbListIter *it;
|
||||
SdbKv *kv;
|
||||
|
||||
ls_foreach (l, it, kv) {
|
||||
showFormat (core, sdbkv_key (kv), 1);
|
||||
}
|
||||
|
@ -2870,6 +2870,7 @@ R_API bool r_core_init(RCore *core) {
|
||||
core->rasm->num = core->num;
|
||||
r_asm_set_user_ptr (core->rasm, core);
|
||||
core->anal = r_anal_new ();
|
||||
core->anal->print = core->print;
|
||||
r_anal_bind (core->anal, &core->rasm->analb);
|
||||
core->gadgets = r_list_newf ((RListFree)r_core_gadget_free);
|
||||
core->anal->ev = core->ev;
|
||||
|
@ -726,6 +726,17 @@ R_API RFlagItem *r_flag_set_next(RFlag *f, const char *name, ut64 off, ut32 size
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API RFlagItem *r_flag_set_inspace(RFlag *f, const char *space, const char *name, ut64 off, ut32 size) {
|
||||
if (space) {
|
||||
r_flag_space_push (f, space);
|
||||
}
|
||||
RFlagItem *fi = r_flag_set (f, name, off, size);
|
||||
if (space) {
|
||||
r_flag_space_pop (f);
|
||||
}
|
||||
return fi;
|
||||
}
|
||||
|
||||
/* create or modify an existing flag item with the given name and parameters.
|
||||
* The realname of the item will be the same as the name.
|
||||
* NULL is returned in case of any errors during the process. */
|
||||
@ -808,6 +819,12 @@ R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name) {
|
||||
return update_flag_item_name (f, item, name, false);
|
||||
}
|
||||
|
||||
R_API void r_flag_item_set_type(RFlagItem *fi, const char *type) {
|
||||
r_return_if_fail (fi && type);
|
||||
free (fi->type);
|
||||
fi->type = strdup (type);
|
||||
}
|
||||
|
||||
/* unset the given flag item.
|
||||
* returns true if the item is successfully unset, false otherwise.
|
||||
*
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <r_io.h>
|
||||
#include <r_reg.h>
|
||||
#include <r_list.h>
|
||||
#include <r_util/r_print.h>
|
||||
#include <r_search.h>
|
||||
#include <r_util.h>
|
||||
#include <r_bind.h>
|
||||
@ -652,6 +653,7 @@ typedef struct r_anal_t {
|
||||
RSpaces zign_spaces;
|
||||
char *zign_path; // dir.zigns
|
||||
PrintfCallback cb_printf;
|
||||
RPrint *print;
|
||||
//moved from RAnalFcn
|
||||
Sdb *sdb; // root
|
||||
Sdb *sdb_pins;
|
||||
@ -2154,6 +2156,14 @@ R_API void r_anal_base_type_free(RAnalBaseType *type);
|
||||
R_API RAnalBaseType *r_anal_base_type_new(RAnalBaseTypeKind kind);
|
||||
R_API void r_anal_dwarf_process_info(const RAnal *anal, RAnalDwarfContext *ctx);
|
||||
R_API void r_anal_dwarf_integrate_functions(RAnal *anal, RFlag *flags, Sdb *dwarf_sdb);
|
||||
/* global.c */
|
||||
R_API RFlagItem *r_anal_global_get(RAnal *anal, ut64 addr);
|
||||
R_API bool r_anal_global_add(RAnal *anal, ut64 addr, const char *type_name, const char *name);
|
||||
R_API bool r_anal_global_del(RAnal *anal, ut64 addr);
|
||||
R_API bool r_anal_global_retype(RAnal *anal, ut64 addr, const char *new_type);
|
||||
R_API bool r_anal_global_rename(RAnal *anal, ut64 addr, const char *new_name);
|
||||
R_API const char *r_anal_global_get_type(RAnal *anal, ut64 addr);
|
||||
|
||||
/* plugin pointers */
|
||||
extern RAnalPlugin r_anal_plugin_null;
|
||||
extern RAnalPlugin r_anal_plugin_6502;
|
||||
|
@ -45,6 +45,7 @@ typedef struct r_flag_item_t {
|
||||
char *color; /* item color */
|
||||
char *comment; /* item comment */
|
||||
char *alias; /* used to define a flag based on a math expression (e.g. foo + 3) */
|
||||
char *type;
|
||||
} RFlagItem;
|
||||
|
||||
typedef struct r_flag_t {
|
||||
@ -110,9 +111,11 @@ R_API const RList* /*<RFlagItem*>*/ r_flag_get_list(RFlag *f, ut64 off);
|
||||
R_API char *r_flag_get_liststr(RFlag *f, ut64 off);
|
||||
R_API bool r_flag_unset(RFlag *f, RFlagItem *item);
|
||||
R_API bool r_flag_unset_name(RFlag *f, const char *name);
|
||||
R_API void r_flag_item_set_type(RFlagItem *fi, const char *type);
|
||||
R_API bool r_flag_unset_off(RFlag *f, ut64 addr);
|
||||
R_API void r_flag_unset_all (RFlag *f);
|
||||
R_API RFlagItem *r_flag_set(RFlag *fo, const char *name, ut64 addr, ut32 size);
|
||||
R_API RFlagItem *r_flag_set_inspace(RFlag *f, const char *space, const char *name, ut64 off, ut32 size);
|
||||
R_API RFlagItem *r_flag_set_next(RFlag *fo, const char *name, ut64 addr, ut32 size);
|
||||
R_API void r_flag_item_set_alias(RFlagItem *item, const char *alias);
|
||||
R_API void r_flag_item_free (RFlagItem *item);
|
||||
|
@ -1621,7 +1621,7 @@ R_API int r_print_format_struct_size(RPrint *p, const char *f, int mode, int n)
|
||||
if (n >= 5) { // This is the nesting level, is this not a bit arbitrary?!
|
||||
return 0;
|
||||
}
|
||||
const char *fmt2 = sdb_get (p->formats, f, NULL);
|
||||
const char *fmt2 = p? sdb_get (p->formats, f, NULL): NULL;
|
||||
if (!fmt2) {
|
||||
fmt2 = f;
|
||||
}
|
||||
|
@ -60,21 +60,21 @@ FILE=bins/mach0/objc-employee
|
||||
CMDS=.ic*;tc
|
||||
EXPECT=<<EOF
|
||||
struct Employee {
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
};
|
||||
struct NSString {
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
};
|
||||
enum mach0_build_platform {
|
||||
MACOS = 1,
|
||||
@ -288,21 +288,21 @@ FILE=bins/mach0/objc-employee-ios14-arm64
|
||||
CMDS=.ic*;tc
|
||||
EXPECT=<<EOF
|
||||
struct Employee {
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
};
|
||||
struct NSString {
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
};
|
||||
enum mach0_build_platform {
|
||||
MACOS = 1,
|
||||
@ -515,21 +515,21 @@ FILE=bins/mach0/objc-employee-ios14-arm64e
|
||||
CMDS=.ic*;tc
|
||||
EXPECT=<<EOF
|
||||
struct Employee {
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
struct objc_class *isa;
|
||||
int16_t _shortWord;
|
||||
struct NSString *_username;
|
||||
struct NSString *_firstName;
|
||||
uint64_t _wideWord;
|
||||
void *username;
|
||||
void *firstName;
|
||||
void *shortWord;
|
||||
void *wideWord;
|
||||
};
|
||||
struct NSString {
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
void *p0;
|
||||
size_t p1;
|
||||
char *str;
|
||||
int len;
|
||||
};
|
||||
enum mach0_build_platform {
|
||||
MACOS = 1,
|
||||
|
@ -881,9 +881,9 @@ tsc three_elements
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
struct three_elements {
|
||||
int32_t x;
|
||||
char y;
|
||||
float z;
|
||||
int32_t x;
|
||||
char y;
|
||||
float z;
|
||||
};
|
||||
EOF
|
||||
RUN
|
||||
@ -896,9 +896,9 @@ tsc with_array
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
struct with_array {
|
||||
int32_t x;
|
||||
char y[50];
|
||||
float z;
|
||||
int32_t x;
|
||||
char y[50];
|
||||
float z;
|
||||
};
|
||||
EOF
|
||||
RUN
|
||||
@ -925,9 +925,9 @@ tuc x
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
union x {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t z;
|
||||
};
|
||||
EOF
|
||||
RUN
|
||||
|
Loading…
x
Reference in New Issue
Block a user