mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 07:00:30 +00:00
Reuse R_PERM in RAnalVarAccess.type instead of custom enum ##analysis
This commit is contained in:
parent
c9b159c265
commit
668984c309
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -7,6 +7,7 @@
|
||||
// still required by core in lot of places
|
||||
#define USE_VARSUBS 0
|
||||
|
||||
#include <r_cons.h>
|
||||
#include <r_types.h>
|
||||
#include <r_io.h>
|
||||
#include <r_esil.h>
|
||||
@ -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_cons.h>
|
||||
R_API char *r_anal_data_tostring(RAnalData *d, RConsPrintablePalette *pal);
|
||||
|
||||
/* meta
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user