From 668984c309e0705f0790dd03b46c8a85fa1e67fc Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 9 Jul 2024 13:36:24 +0200 Subject: [PATCH] Reuse R_PERM in RAnalVarAccess.type instead of custom enum ##analysis --- libr/anal/var.c | 14 +++++++------- libr/core/canal.c | 26 ++++++++++++-------------- libr/core/cmd_anal.inc.c | 8 ++++---- libr/include/r_anal.h | 23 ++++++++++++----------- libr/include/r_types.h | 2 ++ test/unit/test_anal_var.c | 16 ++++++++-------- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/libr/anal/var.c b/libr/anal/var.c index eef6795095e93..0c1f4a69a4f94 100644 --- a/libr/anal/var.c +++ b/libr/anal/var.c @@ -1,4 +1,4 @@ -/* radare - LGPL - Copyright 2010-2023 - pancake, oddcoder */ +/* radare - LGPL - Copyright 2010-2024 - pancake, oddcoder */ #define R_LOG_ORIGIN "anal.var" @@ -632,7 +632,7 @@ R_API RAnalVar *r_anal_var_get_dst_var(RAnalVar *var) { r_return_val_if_fail (var, NULL); RAnalVarAccess *acc; r_vector_foreach (&var->accesses, acc) { - if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_READ)) { + if (!(acc->type & R_PERM_R)) { continue; } ut64 addr = var->fcn->addr + acc->offset; @@ -644,7 +644,7 @@ R_API RAnalVar *r_anal_var_get_dst_var(RAnalVar *var) { continue; } RAnalVarAccess *other_acc = r_anal_var_get_access_at (used_var, addr); - if (other_acc && other_acc->type & R_ANAL_VAR_ACCESS_TYPE_WRITE) { + if (other_acc && other_acc->type & R_PERM_W) { return used_var; } } @@ -1003,7 +1003,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char } const int maxarg = 32; // TODO: use maxarg ? - int rw = (op->direction == R_ANAL_OP_DIR_WRITE) ? R_ANAL_VAR_ACCESS_TYPE_WRITE : R_ANAL_VAR_ACCESS_TYPE_READ; + int rw = (op->direction == R_ANAL_OP_DIR_WRITE) ? R_PERM_W : R_PERM_R; if (*sign == '+') { const bool isarg = type == R_ANAL_VAR_KIND_SPV ? ptr >= fcn->stack : ptr >= fcn->bp_off; const char *pfx = isarg ? ARGPREFIX : VARPREFIX; @@ -1348,7 +1348,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int reg_set[i] = 1; } if (var) { - r_anal_var_set_access (var, var->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); + r_anal_var_set_access (var, var->regname, op->addr, R_PERM_R, 0); r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, var->name); } } @@ -1367,7 +1367,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int } RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname); if (newvar) { - r_anal_var_set_access (newvar, newvar->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); + r_anal_var_set_access (newvar, newvar->regname, op->addr, R_PERM_R, 0); } r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname); free (vname); @@ -1392,7 +1392,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int } RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname); if (newvar) { - r_anal_var_set_access (newvar, newvar->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); + r_anal_var_set_access (newvar, newvar->regname, op->addr, R_PERM_R, 0); } r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname); free (vname); diff --git a/libr/core/canal.c b/libr/core/canal.c index f0353cad0d86f..ed2627673edda 100644 --- a/libr/core/canal.c +++ b/libr/core/canal.c @@ -5228,10 +5228,12 @@ typedef struct { ut64 initial_sp; } EsilBreakCtx; -static const char *reg_name_for_access(RAnalOp* op, RAnalVarAccessType type) { +typedef int RPerm; + +static const char *reg_name_for_access(RAnalOp* op, RPerm type) { RAnalValue *dst = r_vector_at (&op->dsts, 0); RAnalValue *src = r_vector_at (&op->srcs, 0); - if (type == R_ANAL_VAR_ACCESS_TYPE_WRITE) { + if (type == R_PERM_W) { if (dst) { return dst->reg; } @@ -5241,11 +5243,11 @@ static const char *reg_name_for_access(RAnalOp* op, RAnalVarAccessType type) { return NULL; } -static ut64 delta_for_access(RAnalOp *op, RAnalVarAccessType type) { +static ut64 delta_for_access(RAnalOp *op, RPerm type) { RAnalValue *dst = r_vector_at (&op->dsts, 0); RAnalValue *src0 = r_vector_at (&op->srcs, 0); RAnalValue *src1 = r_vector_at (&op->srcs, 1); - if (type == R_ANAL_VAR_ACCESS_TYPE_WRITE) { + if (type == R_PERM_W) { if (dst) { return dst->imm + dst->delta; } @@ -5260,10 +5262,8 @@ static ut64 delta_for_access(RAnalOp *op, RAnalVarAccessType type) { return 0; } -static void handle_var_stack_access(REsil *esil, ut64 addr, RAnalVarAccessType type, int len) { - if (!esil || !esil->user) { - return; - } +static void handle_var_stack_access(REsil *esil, ut64 addr, RPerm type, int len) { + R_RETURN_IF_FAIL (esil && esil->user); EsilBreakCtx *ctx = esil->user; const char *regname = reg_name_for_access (ctx->op, type); if (ctx->fcn && regname) { @@ -5303,7 +5303,7 @@ static bool is_stack(RIO *io, ut64 addr) { static bool esilbreak_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { RCore *core = esil->anal->coreb.core; - handle_var_stack_access (esil, addr, R_ANAL_VAR_ACCESS_TYPE_WRITE, len); + handle_var_stack_access (esil, addr, R_PERM_W, len); // ignore writes in stack if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) { if (!is_stack (core->io, addr)) { @@ -5329,7 +5329,7 @@ static bool esilbreak_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) { if (addr != UT64_MAX) { esilbreak_last_read = addr; } - handle_var_stack_access (esil, addr, R_ANAL_VAR_ACCESS_TYPE_READ, len); + handle_var_stack_access (esil, addr, R_PERM_R, len); if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) { ut64 refptr = UT64_MAX; bool trace = true; @@ -5376,14 +5376,12 @@ static bool esilbreak_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) { } static bool esilbreak_reg_write(REsil *esil, const char *name, ut64 *val) { - if (!esil || !esil->anal || !esil->user) { - return false; - } + R_RETURN_VAL_IF_FAIL (esil && esil->anal && esil->user, false); RAnal *anal = esil->anal; EsilBreakCtx *ctx = esil->user; RAnalOp *op = ctx->op; RCore *core = anal->coreb.core; - handle_var_stack_access (esil, *val, R_ANAL_VAR_ACCESS_TYPE_PTR, esil->anal->config->bits / 8); + handle_var_stack_access (esil, *val, R_PERM_NONE, esil->anal->config->bits / 8); const bool is_arm = !strcmp (core->anal->config->arch, "arm"); //specific case to handle blx/bx cases in arm through emulation // XXX this thing creates a lot of false positives diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index a90d6a33a0e3f..0dc3cb41061b4 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -1517,7 +1517,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c r_cons_printf ("* %s\n", var->name); RAnalVarAccess *acc; r_vector_foreach (&var->accesses, acc) { - if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_READ)) { + if (!(acc->type & R_PERM_R)) { continue; } r_cons_printf ("R 0x%"PFMT64x" ", fcn->addr + acc->offset); @@ -1525,7 +1525,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c r_core_print_disasm_instructions (core, 0, 1); } r_vector_foreach (&var->accesses, acc) { - if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_WRITE)) { + if (!(acc->type & R_PERM_W)) { continue; } r_cons_printf ("W 0x%"PFMT64x" ", fcn->addr + acc->offset); @@ -1551,7 +1551,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c r_list_free (list); return; } - int access_type = type == 'R' ? R_ANAL_VAR_ACCESS_TYPE_READ : R_ANAL_VAR_ACCESS_TYPE_WRITE; + int access_type = type == 'R' ? R_PERM_R : R_PERM_W; if (pj) { pj_a (pj); } @@ -2049,7 +2049,7 @@ static int var_cmd(RCore *core, const char *str) { res = false; break; } - int rw = (str[1] == 'g') ? R_ANAL_VAR_ACCESS_TYPE_READ : R_ANAL_VAR_ACCESS_TYPE_WRITE; + int rw = (str[1] == 'g') ? R_PERM_R : R_PERM_W; int ptr = *var->type == 's' ? idx - fcn->maxstack : idx; RAnalOp *op = r_core_anal_op (core, addr, 0); const char *ireg = op ? op->ireg : NULL; diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index cd215c07a22cc..cecccb8e83a93 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -7,6 +7,7 @@ // still required by core in lot of places #define USE_VARSUBS 0 +#include #include #include #include @@ -503,17 +504,19 @@ typedef enum { #define VARPREFIX "var" #define ARGPREFIX "arg" +#if 0 typedef enum { R_ANAL_VAR_ACCESS_TYPE_PTR = 0, R_ANAL_VAR_ACCESS_TYPE_READ = (1 << 0), R_ANAL_VAR_ACCESS_TYPE_WRITE = (1 << 1) } RAnalVarAccessType; +#endif typedef struct r_anal_var_access_t { const char *reg; // register used for access st64 offset; // relative to the function's entrypoint st64 stackptr; // delta added to register to get the var, e.g. [rbp - 0x10] - ut8 type; // RAnalVarAccessType bits + ut8 type; // R_PERM_{R/W/NONE} // TODO: R2_600 what about using rwx instead of custom enum? } RAnalVarAccess; typedef struct r_anal_var_constraint_t { @@ -608,7 +611,8 @@ typedef struct r_anal_bb_t { ut8 *op_bytes; ut8 *parent_reg_arena; int parent_reg_arena_size; -#if R2_590 +#if R2_600 + // for the oppos USE RVec #else ut16 *op_pos; // offsets of instructions in this block, count is ninstr - 1 (first is always 0) @@ -620,7 +624,6 @@ typedef struct r_anal_bb_t { ut64 cmpval; const char *cmpreg; ut32 bbhash; // calculated with xxhash - RList *fcns; RAnal *anal; char *esil; @@ -721,17 +724,17 @@ enum { R_ANAL_ESIL_DFG_TAG_MEM = 64, R_ANAL_ESIL_DFG_TAG_MERGE = 128, R_ANAL_ESIL_DFG_TAG_SIBLING = 256, -}; //RAnalEsilDFGTagType +}; // RAnalEsilDFGTagType typedef struct r_anal_esil_dfg_t { ut32 idx; int fd; RIOBind iob; RReg *reg; - Sdb *regs; //resolves regnames to intervals - RRBTree *vars; //vars represented in regs and mem - RQueue *todo; //todo-queue allocated in this struct for perf - void *insert; //needed for setting regs in dfg + Sdb *regs; // resolves regnames to intervals + RRBTree *vars; // vars represented in regs and mem + RQueue *todo; // todo-queue allocated in this struct for perf + void *insert; // needed for setting regs in dfg RGraph *flow; RGraphNode *cur; RGraphNode *old; @@ -787,7 +790,7 @@ typedef struct r_anal_plugin_t { } RAnalPlugin; /*----------------------------------------------------------------------------------------------*/ -int * (r_anal_compare) (RAnalFunction , RAnalFunction ); +int * (r_anal_compare) (RAnalFunction , RAnalFunction); /*----------------------------------------------------------------------------------------------*/ #ifdef R_API @@ -1021,7 +1024,6 @@ R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le R_API int r_anal_opasm(RAnal *anal, ut64 pc, const char *s, ut8 *outbuf, int outlen); R_API char *r_anal_op_tostring(RAnal *anal, RAnalOp *op); - /* pin */ R_API void r_anal_pin_init(RAnal *a); R_API void r_anal_pin_fini(RAnal *a); @@ -1249,7 +1251,6 @@ R_API int r_anal_data_type(RAnal *a, ut64 da); R_API RAnalData *r_anal_data_new_string(ut64 addr, const char *p, int size, int wide); R_API RAnalData *r_anal_data_new(ut64 addr, int type, ut64 n, const ut8 *buf, int len); R_API void r_anal_data_free(RAnalData *d); -#include R_API char *r_anal_data_tostring(RAnalData *d, RConsPrintablePalette *pal); /* meta diff --git a/libr/include/r_types.h b/libr/include/r_types.h index c529cf189e79c..7a74753aebeb1 100644 --- a/libr/include/r_types.h +++ b/libr/include/r_types.h @@ -79,6 +79,7 @@ #define R_PERM_R 4 #define R_PERM_W 2 #define R_PERM_X 1 +#define R_PERM_NONE 0 #define R_PERM_RW (R_PERM_R|R_PERM_W) #define R_PERM_RX (R_PERM_R|R_PERM_X) #define R_PERM_RWX (R_PERM_R|R_PERM_W|R_PERM_X) @@ -88,6 +89,7 @@ #define R_PERM_PRIV 16 #define R_PERM_ACCESS 32 #define R_PERM_CREAT 64 +// R2_600 typedef int RPerm; // HACK to fix capstone-android-mips build diff --git a/test/unit/test_anal_var.c b/test/unit/test_anal_var.c index 768fc102e82b5..d319086bed609 100644 --- a/test/unit/test_anal_var.c +++ b/test/unit/test_anal_var.c @@ -95,10 +95,10 @@ bool test_r_anal_var(void) { // accesses - r_anal_var_set_access (a, "rsp", 0x120, R_ANAL_VAR_ACCESS_TYPE_READ, 42); - r_anal_var_set_access (a, "rbp", 0x130, R_ANAL_VAR_ACCESS_TYPE_WRITE, 13); - r_anal_var_set_access (b, "rsp", 0x120, R_ANAL_VAR_ACCESS_TYPE_WRITE, 123); - r_anal_var_set_access (b, "rbp", 0x10, R_ANAL_VAR_ACCESS_TYPE_WRITE, -100); + r_anal_var_set_access (a, "rsp", 0x120, R_PERM_R, 42); + r_anal_var_set_access (a, "rbp", 0x130, R_PERM_W, 13); + r_anal_var_set_access (b, "rsp", 0x120, R_PERM_W, 123); + r_anal_var_set_access (b, "rbp", 0x10, R_PERM_W, -100); st64 stackptr = r_anal_function_get_var_stackptr_at (fcn, -0x10, 0x12345); mu_assert_eq (stackptr, ST64_MAX, "unset stackptr"); @@ -135,14 +135,14 @@ bool test_r_anal_var(void) { used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL); // addresses should stay the same mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); - r_anal_var_set_access (a, "rbp", 0xffffffffffff0130UL, R_ANAL_VAR_ACCESS_TYPE_READ, 42); + r_anal_var_set_access (a, "rbp", 0xffffffffffff0130UL, R_PERM_R, 42); used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert ("used vars", r_pvector_contains (used_vars, a)); used_vars = r_anal_function_get_vars_used_at (fcn, 0x123); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); - r_anal_var_set_access (a, "rbp" , 0x123, R_ANAL_VAR_ACCESS_TYPE_READ, 42); + r_anal_var_set_access (a, "rbp" , 0x123, R_PERM_R, 42); used_vars = r_anal_function_get_vars_used_at (fcn, 0x123); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert ("used vars", r_pvector_contains (used_vars, a)); @@ -167,7 +167,7 @@ bool test_r_anal_var(void) { used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); - r_anal_var_set_access (a, "rbp", 0x8000000000000100, R_ANAL_VAR_ACCESS_TYPE_READ, 987321); + r_anal_var_set_access (a, "rbp", 0x8000000000000100, R_PERM_R, 987321); used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert ("used vars", r_pvector_contains (used_vars, a)); @@ -176,7 +176,7 @@ bool test_r_anal_var(void) { used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); - r_anal_var_set_access (a, "rbp", 0x7ffffffffffffe00, R_ANAL_VAR_ACCESS_TYPE_READ, 777); + r_anal_var_set_access (a, "rbp", 0x7ffffffffffffe00, R_PERM_R, 777); used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert ("used vars", r_pvector_contains (used_vars, a));