mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-07 10:33:30 +00:00
RAnalValue no longer refs an RRegItem ##analysis
* Highly reduce memory usage, faster analysis and fix some memleaks and uafs
This commit is contained in:
parent
a185dd7288
commit
f40ce7e9e6
@ -327,3 +327,4 @@ Starting application, this might take some time...
|
||||
Do you want to restart to install these updates now or try tonight?
|
||||
Updates available
|
||||
This binary has not been analyzed. Would you like to analyze it now?
|
||||
The software is up to date. Just kidding, git pull again
|
||||
|
120
libr/anal/fcn.c
120
libr/anal/fcn.c
@ -179,7 +179,8 @@ static bool is_delta_pointer_table(ReadAhead *ra, RAnal *anal, RAnalFunction *fc
|
||||
RAnalOp omov_aop = {0};
|
||||
RAnalOp mov_aop = {0};
|
||||
RAnalOp add_aop = {0};
|
||||
RRegItem *reg_src = NULL, *o_reg_dst = NULL;
|
||||
const char *reg_src = NULL;
|
||||
const char *o_reg_dst = NULL;
|
||||
RAnalValue cur_scr, cur_dst = {0};
|
||||
read_ahead (ra, anal, addr, (ut8*)buf, sizeof (buf));
|
||||
bool isValid = false;
|
||||
@ -233,7 +234,16 @@ static bool is_delta_pointer_table(ReadAhead *ra, RAnal *anal, RAnalFunction *fc
|
||||
&& mov_aop.disp && mov_aop.disp != UT64_MAX) {
|
||||
// disp in this case should be tbl_loc_off
|
||||
*jmptbl_addr += mov_aop.disp;
|
||||
if (o_reg_dst && reg_src && o_reg_dst->offset == reg_src->offset && omov_aop.disp != UT64_MAX) {
|
||||
#if 1
|
||||
if (o_reg_dst && reg_src && omov_aop.disp != UT64_MAX) {
|
||||
RRegItem *ri0 = r_reg_get (anal->reg, o_reg_dst, R_REG_TYPE_GPR);
|
||||
RRegItem *ri1 = r_reg_get (anal->reg, reg_src, R_REG_TYPE_GPR);
|
||||
if (ri0 && ri1 && ri0->offset == ri1->offset) {
|
||||
*casetbl_addr += omov_aop.disp;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (o_reg_dst && reg_src && !strcmp (o_reg_dst, reg_src) && omov_aop.disp != UT64_MAX) {
|
||||
// Special case for indirection
|
||||
// lea reg1, [base_addr]
|
||||
// movzx reg2, byte [reg1 + tbl_off + casetbl_loc_off]
|
||||
@ -242,6 +252,7 @@ static bool is_delta_pointer_table(ReadAhead *ra, RAnal *anal, RAnalFunction *fc
|
||||
// jmp reg3
|
||||
*casetbl_addr += omov_aop.disp;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0
|
||||
// required for the last jmptbl.. but seems to work without it and breaks other tests
|
||||
@ -293,7 +304,7 @@ static ut64 try_get_cmpval_from_parents(RAnal *anal, RAnalFunction *fcn, RAnalBl
|
||||
|
||||
static bool regs_exist(RAnalValue *src, RAnalValue *dst) {
|
||||
r_return_val_if_fail (src && dst, false);
|
||||
return src->reg && dst->reg && src->reg->name && dst->reg->name;
|
||||
return src->reg && dst->reg;
|
||||
}
|
||||
|
||||
// 0 if not skipped; 1 if skipped; 2 if skipped before
|
||||
@ -539,13 +550,13 @@ static inline bool has_vars(RAnal *anal, ut64 addr) {
|
||||
}
|
||||
|
||||
static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int depth) {
|
||||
RRegItem *variadic_reg = NULL;
|
||||
const char *variadic_reg = NULL;
|
||||
ReadAhead ra = {0};
|
||||
ra.cache_addr = UT64_MAX; // invalidate the cache
|
||||
char *bp_reg = NULL;
|
||||
char *sp_reg = NULL;
|
||||
char *op_dst = NULL;
|
||||
char *op_src = NULL;
|
||||
const char *bp_reg = NULL;
|
||||
const char *sp_reg = NULL;
|
||||
const char *op_dst = NULL;
|
||||
const char *op_src = NULL;
|
||||
if (depth < -1) {
|
||||
// only happens when we want to analyze 1 basic block
|
||||
return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
|
||||
@ -557,9 +568,9 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
|
||||
// TODO Store all this stuff in the heap so we save memory in the stack
|
||||
RAnalOp *op = NULL;
|
||||
RAnalValue *dst = NULL, *src0 = NULL, *src1 = NULL;
|
||||
char *movbasereg = NULL;
|
||||
const char *movbasereg = NULL;
|
||||
const int addrbytes = anal->iob.io ? anal->iob.io->addrbytes : 1;
|
||||
char *last_reg_mov_lea_name = NULL;
|
||||
const char *last_reg_mov_lea_name = NULL;
|
||||
RAnalBlock *bb = NULL;
|
||||
RAnalBlock *bbg = NULL;
|
||||
int ret = R_ANAL_RET_END, skip_ret = 0;
|
||||
@ -678,18 +689,18 @@ static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int
|
||||
const char *_sp_reg = anal->reg->name[R_REG_NAME_SP];
|
||||
const bool has_stack_regs = _bp_reg && _sp_reg;
|
||||
if (has_stack_regs) {
|
||||
bp_reg = strdup (_bp_reg);
|
||||
sp_reg = strdup (_sp_reg);
|
||||
bp_reg = _bp_reg;
|
||||
sp_reg = _sp_reg;
|
||||
}
|
||||
if (is_amd64) {
|
||||
variadic_reg = r_reg_get (anal->reg, "rax", R_REG_TYPE_GPR);
|
||||
variadic_reg = "rax";
|
||||
}
|
||||
bool has_variadic_reg = !!variadic_reg;
|
||||
|
||||
op = r_anal_op_new ();
|
||||
while (addrbytes * idx < maxlen) {
|
||||
if (!last_is_reg_mov_lea) {
|
||||
R_FREE (last_reg_mov_lea_name);
|
||||
last_reg_mov_lea_name = NULL;
|
||||
}
|
||||
if (anal->limit && anal->limit->to <= addr + idx) {
|
||||
break;
|
||||
@ -724,11 +735,9 @@ repeat:
|
||||
gotoBeach (R_ANAL_RET_END);
|
||||
}
|
||||
dst = r_vector_at (&op->dsts, 0);
|
||||
free (op_dst);
|
||||
op_dst = (dst && dst->reg && dst->reg->name)? strdup (dst->reg->name): NULL;
|
||||
op_dst = dst? dst->reg: NULL;
|
||||
src0 = r_vector_at (&op->srcs, 0);
|
||||
free (op_src);
|
||||
op_src = (src0 && src0->reg && src0->reg->name) ? strdup (src0->reg->name): NULL;
|
||||
op_src = src0 ? src0->reg: NULL;
|
||||
src1 = r_vector_at (&op->srcs, 1);
|
||||
|
||||
if (anal->opt.nopskip && fcn->addr == at) {
|
||||
@ -916,25 +925,18 @@ repeat:
|
||||
fcn->bp_off = fcn->stack;
|
||||
}
|
||||
// Is this a mov of immediate value into a register?
|
||||
if (dst && dst->reg && dst->reg->name && op->val > 0 && op->val != UT64_MAX) {
|
||||
free (last_reg_mov_lea_name);
|
||||
if ((last_reg_mov_lea_name = strdup (dst->reg->name))) {
|
||||
last_reg_mov_lea_val = op->val;
|
||||
last_is_reg_mov_lea = true;
|
||||
}
|
||||
if (dst && dst->reg && op->val > 0 && op->val != UT64_MAX) {
|
||||
last_reg_mov_lea_name = dst->reg;
|
||||
last_reg_mov_lea_val = op->val;
|
||||
last_is_reg_mov_lea = true;
|
||||
}
|
||||
// skip mov reg, reg
|
||||
if (anal->opt.jmptbl && op->scale && op->ireg) {
|
||||
movdisp = op->disp;
|
||||
movscale = op->scale;
|
||||
if (src0 && src0->reg) {
|
||||
free (movbasereg);
|
||||
movbasereg = strdup (src0->reg->name);
|
||||
} else {
|
||||
R_FREE (movbasereg);
|
||||
}
|
||||
movbasereg = src0? src0->reg: NULL;
|
||||
}
|
||||
if (anal->opt.hpskip && regs_exist (src0, dst) && !strcmp (src0->reg->name, dst->reg->name)) {
|
||||
if (anal->opt.hpskip && regs_exist (src0, dst) && !strcmp (src0->reg, dst->reg)) {
|
||||
skip_ret = skip_hp (anal, fcn, op, bb, addr, oplen, delay.un_idx, &idx);
|
||||
if (skip_ret == 1) {
|
||||
r_anal_op_fini (op);
|
||||
@ -985,7 +987,7 @@ repeat:
|
||||
pair->reg = op->reg
|
||||
? strdup (op->reg)
|
||||
: dst && dst->reg
|
||||
? strdup (dst->reg->name)
|
||||
? strdup (dst->reg)
|
||||
: NULL;
|
||||
lea_cnt++;
|
||||
r_list_append (anal->leaddrs, pair);
|
||||
@ -993,17 +995,15 @@ repeat:
|
||||
if (has_stack_regs && op_is_set_bp (op_dst, op_src, bp_reg, sp_reg) ) {
|
||||
fcn->bp_off = fcn->stack - src0->delta;
|
||||
}
|
||||
if (dst && dst->reg && dst->reg->name && op->ptr > 0 && op->ptr != UT64_MAX) {
|
||||
free (last_reg_mov_lea_name);
|
||||
if ((last_reg_mov_lea_name = strdup(dst->reg->name))) {
|
||||
last_reg_mov_lea_val = op->ptr;
|
||||
last_is_reg_mov_lea = true;
|
||||
}
|
||||
if (dst && dst->reg && op->ptr > 0 && op->ptr != UT64_MAX) {
|
||||
last_reg_mov_lea_name = dst->reg;
|
||||
last_reg_mov_lea_val = op->ptr;
|
||||
last_is_reg_mov_lea = true;
|
||||
}
|
||||
#endif
|
||||
// skip lea reg,[reg]
|
||||
if (anal->opt.hpskip && regs_exist (src0, dst)
|
||||
&& !strcmp (src0->reg->name, dst->reg->name)) {
|
||||
&& !strcmp (src0->reg, dst->reg)) {
|
||||
skip_ret = skip_hp (anal, fcn, op, bb, at, oplen, delay.un_idx, &idx);
|
||||
if (skip_ret == 1) {
|
||||
r_anal_op_fini (op);
|
||||
@ -1302,10 +1302,10 @@ repeat:
|
||||
anal->iob.read_at (anal->iob.io, op->addr - op->size, buf, sizeof (buf));
|
||||
if (r_anal_op (anal, prev_op, op->addr - op->size, buf, sizeof (buf), R_ARCH_OP_MASK_VAL) > 0) {
|
||||
RAnalValue *prev_dst = r_vector_at (&prev_op->dsts, 0);
|
||||
bool prev_op_has_dst_name = prev_dst && prev_dst->reg && prev_dst->reg->name;
|
||||
bool op_has_src_name = src0 && src0->reg && src0->reg->name;
|
||||
bool same_reg = (op->ireg && prev_op_has_dst_name && !strcmp (op->ireg, prev_dst->reg->name))
|
||||
|| (op_has_src_name && prev_op_has_dst_name && !strcmp (src0->reg->name, prev_dst->reg->name));
|
||||
bool prev_op_has_dst_name = prev_dst && prev_dst->reg;
|
||||
bool op_has_src_name = src0 && src0->reg;
|
||||
bool same_reg = (op->ireg && prev_op_has_dst_name && !strcmp (op->ireg, prev_dst->reg))
|
||||
|| (op_has_src_name && prev_op_has_dst_name && !strcmp (src0->reg, prev_dst->reg));
|
||||
if (prev_op->type == R_ANAL_OP_TYPE_MOV && prev_op->disp && prev_op->disp != UT64_MAX && same_reg) {
|
||||
// movzx reg, byte [reg + case_table]
|
||||
// jmp dword [reg*4 + jump_table]
|
||||
@ -1420,7 +1420,7 @@ analopfinish:
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_UPUSH:
|
||||
if ((op->type & R_ANAL_OP_TYPE_REG) && last_is_reg_mov_lea && src0 && src0->reg
|
||||
&& src0->reg->name && !strcmp (src0->reg->name, last_reg_mov_lea_name)) {
|
||||
&& src0->reg && !strcmp (src0->reg, last_reg_mov_lea_name)) {
|
||||
last_is_push = true;
|
||||
last_push_addr = last_reg_mov_lea_val;
|
||||
if (anal->iob.is_valid_offset (anal->iob.io, last_push_addr, 1)) {
|
||||
@ -1450,7 +1450,6 @@ analopfinish:
|
||||
break;
|
||||
}
|
||||
if (has_stack_regs && arch_destroys_dst) {
|
||||
// op->dst->reg->name is invalid pointer
|
||||
if (op_is_set_bp (op_dst, op_src, bp_reg, sp_reg) && src1) {
|
||||
switch (op->type & R_ANAL_OP_TYPE_MASK) {
|
||||
case R_ANAL_OP_TYPE_ADD:
|
||||
@ -1479,10 +1478,20 @@ analopfinish:
|
||||
last_is_mov_lr_pc = false;
|
||||
}
|
||||
if (has_variadic_reg && !fcn->is_variadic) {
|
||||
r_unref (variadic_reg);
|
||||
variadic_reg = r_reg_get (anal->reg, "rax", R_REG_TYPE_GPR);
|
||||
bool dst_is_variadic = dst && dst->reg
|
||||
&& variadic_reg && dst->reg->offset == variadic_reg->offset;
|
||||
variadic_reg = "rax";
|
||||
#if 1
|
||||
bool dst_is_variadic = dst && dst->reg && variadic_reg;
|
||||
if (dst_is_variadic) {
|
||||
dst_is_variadic = false;
|
||||
RRegItem *ri0 = r_reg_get (anal->reg, dst->reg, R_REG_TYPE_GPR);
|
||||
RRegItem *ri1 = r_reg_get (anal->reg, variadic_reg, R_REG_TYPE_GPR);
|
||||
if (ri0 && ri1 && ri0->offset == ri1->offset) {
|
||||
dst_is_variadic = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool dst_is_variadic = dst && dst->reg && variadic_reg && !strcmp (dst->reg, variadic_reg);
|
||||
#endif
|
||||
bool op_is_cmp = (op->type == R_ANAL_OP_TYPE_CMP) || op->type == R_ANAL_OP_TYPE_ACMP;
|
||||
if (dst_is_variadic && !op_is_cmp) {
|
||||
has_variadic_reg = false;
|
||||
@ -1494,23 +1503,16 @@ analopfinish:
|
||||
}
|
||||
}
|
||||
beach:
|
||||
r_unref (variadic_reg);
|
||||
free (op_src);
|
||||
free (op_dst);
|
||||
free (bp_reg);
|
||||
free (sp_reg);
|
||||
while (lea_cnt > 0) {
|
||||
r_list_delete (anal->leaddrs, r_list_tail (anal->leaddrs));
|
||||
lea_cnt--;
|
||||
}
|
||||
r_anal_op_free (op);
|
||||
R_FREE (last_reg_mov_lea_name);
|
||||
if (bb && bb->size == 0) {
|
||||
r_anal_function_remove_block (fcn, bb);
|
||||
}
|
||||
r_anal_block_update_hash (bb);
|
||||
r_anal_block_unref (bb);
|
||||
free (movbasereg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2126,8 +2128,8 @@ R_API bool r_anal_function_purity(RAnalFunction *fcn) {
|
||||
static bool can_affect_bp(RAnal *anal, RAnalOp* op) {
|
||||
RAnalValue *dst = r_vector_at (&op->dsts, 0);
|
||||
RAnalValue *src = r_vector_at (&op->srcs, 0);
|
||||
const char *opdreg = (dst && dst->reg) ? dst->reg->name : NULL;
|
||||
const char *opsreg = (src && src->reg) ? src->reg->name : NULL;
|
||||
const char *opdreg = dst? dst->reg: NULL;
|
||||
const char *opsreg = src? src->reg: NULL;
|
||||
const char *bp_name = anal->reg->name[R_REG_NAME_BP];
|
||||
bool dst_is_bp = opdreg && !dst->memref && !strcmp (opdreg, bp_name);
|
||||
bool src_is_bp = opsreg && !src->memref && !strcmp (opsreg, bp_name);
|
||||
@ -2172,7 +2174,7 @@ R_API void r_anal_function_check_bp_use(RAnalFunction *fcn) {
|
||||
case R_ANAL_OP_TYPE_LEA:
|
||||
if (can_affect_bp (anal, &op)) {
|
||||
const char *spreg = anal->reg->name[R_REG_NAME_SP];
|
||||
if (src && src->reg && src->reg->name && strcmp (src->reg->name, spreg)) {
|
||||
if (src && src->reg && strcmp (src->reg, spreg)) {
|
||||
fcn->bp_frame = false;
|
||||
r_anal_op_fini (&op);
|
||||
free (buf);
|
||||
|
@ -1,9 +1,7 @@
|
||||
/* radare - LGPL - Copyright 2010-2022 - nibble, alvaro, pancake, th3str4ng3r */
|
||||
/* radare - LGPL - Copyright 2010-2023 - nibble, alvaro, pancake, th3str4ng3r */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_parse.h>
|
||||
#include <r_util.h>
|
||||
#include <r_list.h>
|
||||
|
||||
#define JMPTBL_MAXSZ 512
|
||||
|
||||
@ -263,13 +261,13 @@ R_API bool try_walkthrough_jmptbl(RAnal *anal, RAnalFunction *fcn, RAnalBlock *b
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool detect_casenum_shift(RAnalOp *op, RRegItem **cmp_reg, st64 *start_casenum_shift) {
|
||||
static bool detect_casenum_shift(RAnalOp *op, const char **cmp_reg, st64 *start_casenum_shift) {
|
||||
if (!*cmp_reg) {
|
||||
return true;
|
||||
}
|
||||
RAnalValue *dst = r_vector_at (&op->dsts, 0);
|
||||
RAnalValue *src = r_vector_at (&op->srcs, 0);
|
||||
if (dst && dst->reg && dst->reg->offset == (*cmp_reg)->offset) {
|
||||
if (dst && dst->reg && !strcmp (dst->reg, *cmp_reg)) {
|
||||
if (op->type == R_ANAL_OP_TYPE_LEA && op->ptr == UT64_MAX) {
|
||||
*start_casenum_shift = -(st64)op->disp;
|
||||
} else if (op->val != UT64_MAX) {
|
||||
@ -307,7 +305,7 @@ R_API bool try_get_delta_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 jmp_a
|
||||
RVector v;
|
||||
r_vector_init (&v, sizeof (ut64), NULL, NULL);
|
||||
int len = 0;
|
||||
RRegItem *cmp_reg = NULL;
|
||||
const char *cmp_reg = NULL;
|
||||
for (i = 0; i + 8 < search_sz; i += len) {
|
||||
len = r_anal_op (anal, &tmp_aop, lea_addr + i, buf + i, search_sz - i, R_ARCH_OP_MASK_BASIC);
|
||||
if (len < 1) {
|
||||
@ -353,8 +351,7 @@ R_API bool try_get_delta_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 jmp_a
|
||||
if (tmp_dst && tmp_dst->reg) {
|
||||
cmp_reg = tmp_dst->reg;
|
||||
} else if (tmp_aop.reg) {
|
||||
r_unref (cmp_reg);
|
||||
cmp_reg = r_reg_get (anal->reg, tmp_aop.reg, R_REG_TYPE_ALL);
|
||||
cmp_reg = tmp_aop.reg;
|
||||
} else if (tmp_src && tmp_src->reg) {
|
||||
cmp_reg = tmp_src->reg;
|
||||
}
|
||||
@ -378,7 +375,6 @@ R_API bool try_get_delta_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 jmp_a
|
||||
r_anal_op_fini (&tmp_aop);
|
||||
}
|
||||
}
|
||||
r_unref (cmp_reg);
|
||||
r_vector_fini (&v);
|
||||
free (buf);
|
||||
return isValid;
|
||||
@ -485,7 +481,7 @@ R_API bool try_get_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 addr, RAnal
|
||||
anal->iob.read_at (anal->iob.io, prev_bb->addr, (ut8 *) bb_buf, prev_bb->size);
|
||||
isValid = false;
|
||||
|
||||
RRegItem *cmp_reg = NULL;
|
||||
const char *cmp_reg = NULL;
|
||||
for (i = prev_bb->ninstr - 1; i >= 0; i--) {
|
||||
const ut64 prev_pos = r_anal_bb_offset_inst (prev_bb, i);
|
||||
const ut64 op_addr = r_anal_bb_opaddr_i (prev_bb, i);
|
||||
@ -527,8 +523,7 @@ R_API bool try_get_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 addr, RAnal
|
||||
if (tmp_dst && tmp_dst->reg) {
|
||||
cmp_reg = tmp_dst->reg;
|
||||
} else if (tmp_aop.reg) {
|
||||
r_unref (cmp_reg);
|
||||
cmp_reg = r_reg_get (anal->reg, tmp_aop.reg, R_REG_TYPE_ALL);
|
||||
cmp_reg = tmp_aop.reg;
|
||||
} else if (tmp_src && tmp_src->reg) {
|
||||
cmp_reg = tmp_src->reg;
|
||||
}
|
||||
@ -557,7 +552,6 @@ R_API bool try_get_jmptbl_info(RAnal *anal, RAnalFunction *fcn, ut64 addr, RAnal
|
||||
r_anal_op_fini (&tmp_aop);
|
||||
}
|
||||
}
|
||||
r_unref (cmp_reg);
|
||||
free (bb_buf);
|
||||
// eprintf ("switch at 0x%" PFMT64x "\n\tdefault case 0x%" PFMT64x "\n\t#cases: %d\n",
|
||||
// addr,
|
||||
|
@ -678,7 +678,7 @@ R_API int r_anal_op_reg_delta(RAnal *anal, ut64 addr, const char *name) {
|
||||
RAnalValue *dst = NULL;
|
||||
if (r_anal_op (anal, &op, addr, buf, sizeof (buf), R_ARCH_OP_MASK_ALL) > 0) {
|
||||
dst = r_vector_at (&op.dsts, 0);
|
||||
if (dst && dst->reg && dst->reg->name && (!name || !strcmp (dst->reg->name, name))) {
|
||||
if (dst && dst->reg && (!name || !strcmp (dst->reg, name))) {
|
||||
if (r_vector_length (&op.srcs) > 0) {
|
||||
r_anal_op_fini (&op);
|
||||
return ((RAnalValue*)r_vector_at (&op.srcs, 0))->delta;
|
||||
|
@ -4262,36 +4262,29 @@ jmp $$ + 4 + ( [delta] * 2 )
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_valid(arm_reg reg) {
|
||||
static inline bool is_valid(arm_reg reg) {
|
||||
return reg != ARM_REG_INVALID;
|
||||
}
|
||||
|
||||
// XXX this function is a disaster
|
||||
static int parse_reg_name(RReg *reg, RRegItem **reg_base, RRegItem **reg_delta, csh handle, cs_insn *insn, int reg_num) {
|
||||
static const char *parse_reg_name(RReg *reg, const char **reg_delta, csh handle, cs_insn *insn, int reg_num) {
|
||||
cs_arm_op armop = INSOP (reg_num);
|
||||
switch (armop.type) {
|
||||
case ARM_OP_REG:
|
||||
r_unref (*reg_base);
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.reg), R_REG_TYPE_ALL);
|
||||
break;
|
||||
return cs_reg_name (handle, armop.reg);
|
||||
case ARM_OP_MEM:
|
||||
if (is_valid (armop.mem.base) && is_valid (armop.mem.index)) {
|
||||
r_unref (*reg_base);
|
||||
r_unref (*reg_delta);
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.base), R_REG_TYPE_ALL);
|
||||
*reg_delta = r_reg_get (reg, cs_reg_name (handle, armop.mem.index), R_REG_TYPE_ALL);
|
||||
*reg_delta = cs_reg_name (handle, armop.mem.index);
|
||||
return cs_reg_name (handle, armop.mem.base);
|
||||
} else if (is_valid (armop.mem.base)) {
|
||||
r_unref (*reg_base);
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.base), R_REG_TYPE_ALL);
|
||||
return cs_reg_name (handle, armop.mem.base);
|
||||
} else if (is_valid (armop.mem.index)) {
|
||||
r_unref (*reg_base);
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.index), R_REG_TYPE_ALL);
|
||||
return cs_reg_name (handle, armop.mem.index);
|
||||
}
|
||||
break;
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_valid64(arm64_reg reg) {
|
||||
@ -4308,29 +4301,30 @@ static char *reg_list[] = {
|
||||
"x30"
|
||||
};
|
||||
|
||||
static int parse_reg64_name(RReg *reg, RRegItem **reg_base, RRegItem **reg_delta, csh handle, cs_insn *insn, int reg_num) {
|
||||
static const char *parse_reg64_name(RReg *reg, const char **reg_delta, csh handle, cs_insn *insn, int reg_num) {
|
||||
const char *reg_base = NULL;
|
||||
cs_arm64_op armop = INSOP64 (reg_num);
|
||||
switch (armop.type) {
|
||||
case ARM64_OP_REG:
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.reg), R_REG_TYPE_ALL);
|
||||
reg_base = cs_reg_name (handle, armop.reg);
|
||||
break;
|
||||
case ARM64_OP_MEM:
|
||||
if (is_valid64 (armop.mem.base) && is_valid64 (armop.mem.index)) {
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.base), R_REG_TYPE_ALL);
|
||||
*reg_delta = r_reg_get (reg, cs_reg_name (handle, armop.mem.index), R_REG_TYPE_ALL);
|
||||
reg_base = cs_reg_name (handle, armop.mem.base);
|
||||
*reg_delta = cs_reg_name (handle, armop.mem.index);
|
||||
} else if (is_valid64 (armop.mem.base)) {
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.base), R_REG_TYPE_ALL);
|
||||
reg_base = cs_reg_name (handle, armop.mem.base);
|
||||
} else if (is_valid64 (armop.mem.index)) {
|
||||
*reg_base = r_reg_get (reg, cs_reg_name (handle, armop.mem.index), R_REG_TYPE_ALL);
|
||||
reg_base = cs_reg_name (handle, armop.mem.index);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (*reg_base && *(*reg_base)->name == 'w') {
|
||||
*reg_base = r_reg_get (reg, reg_list[atoi ((*reg_base)->name + 1)], R_REG_TYPE_ALL);
|
||||
if (reg_base && *reg_base == 'w') {
|
||||
reg_base = reg_list[atoi (reg_base + 1)]; // XXX dont use atoi
|
||||
}
|
||||
return 0;
|
||||
return reg_base;
|
||||
}
|
||||
|
||||
static void set_opdir(RAnalOp *op) {
|
||||
@ -4364,9 +4358,9 @@ static void set_src_dst(RReg *reg, RAnalValue *val, csh *handle, cs_insn *insn,
|
||||
cs_arm_op armop = INSOP (x);
|
||||
cs_arm64_op arm64op = INSOP64 (x);
|
||||
if (bits == 64) {
|
||||
parse_reg64_name (reg, &val->reg, &val->regdelta, *handle, insn, x);
|
||||
val->reg = parse_reg64_name (reg, &val->regdelta, *handle, insn, x);
|
||||
} else {
|
||||
parse_reg_name (reg, &val->reg, &val->regdelta, *handle, insn, x);
|
||||
val->reg = parse_reg_name (reg, &val->regdelta, *handle, insn, x);
|
||||
}
|
||||
if (bits == 64) {
|
||||
switch (arm64op.type) {
|
||||
|
@ -110,8 +110,8 @@ static inline void gb_anal_jmp_hl(RReg *reg, RAnalOp *op) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "pc", R_REG_TYPE_GPR);
|
||||
src->reg = r_reg_get (reg, "hl", R_REG_TYPE_GPR);
|
||||
dst->reg = "pc";
|
||||
src->reg = "hl";
|
||||
r_strbuf_set (&op->esil, "hl,pc,:=");
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ static inline void gb_anal_id(RAnal *anal, RAnalOp *op, const ut8 data) {
|
||||
src->absolute = true;
|
||||
if (data == 0x34 || data == 0x35) {
|
||||
dst->memref = 1;
|
||||
dst->reg = r_reg_get (anal->reg, "hl", R_REG_TYPE_GPR);
|
||||
dst->reg = "hl";
|
||||
if (op->type == R_ANAL_OP_TYPE_ADD) {
|
||||
r_strbuf_set (&op->esil, "1,hl,[1],+,hl,=[1],3,$c,H,:=,$z,Z,:=,0,N,:=");
|
||||
} else {
|
||||
@ -131,14 +131,14 @@ static inline void gb_anal_id(RAnal *anal, RAnalOp *op, const ut8 data) {
|
||||
}
|
||||
} else {
|
||||
if (!(data & (1<<2))) {
|
||||
dst->reg = r_reg_get (anal->reg, regs_16[data>>4], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_16[data>>4];
|
||||
if (op->type == R_ANAL_OP_TYPE_ADD) {
|
||||
r_strbuf_setf (&op->esil, "1,%s,+=", regs_16[data>>4]);
|
||||
} else {
|
||||
r_strbuf_setf (&op->esil, "1,%s,-=", regs_16[data >> 4]);
|
||||
}
|
||||
} else {
|
||||
dst->reg = r_reg_get (anal->reg, regs_8[data>>3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_8[data>>3];
|
||||
if (op->type == R_ANAL_OP_TYPE_ADD) {
|
||||
r_strbuf_setf (&op->esil, "1,%s,+=,3,$c,H,:=,$z,Z,:=,0,N,:=", regs_8[data>>3]);
|
||||
} else {
|
||||
@ -152,8 +152,8 @@ static inline void gb_anal_add_hl(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "hl", R_REG_TYPE_GPR);
|
||||
src->reg = r_reg_get (reg, regs_16[((data & 0xf0)>>4)], R_REG_TYPE_GPR);
|
||||
dst->reg = "hl";
|
||||
src->reg = regs_16[((data & 0xf0)>>4)];
|
||||
r_strbuf_setf (&op->esil, "%s,hl,+=,0,N,:=", regs_16[((data & 0xf0)>>4)]); //hl+=<reg>,N=0
|
||||
}
|
||||
|
||||
@ -161,7 +161,7 @@ static inline void gb_anal_add_sp(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "sp", R_REG_TYPE_GPR);
|
||||
dst->reg = "sp";
|
||||
src->imm = (st8)data;
|
||||
if (data < 128) {
|
||||
r_strbuf_setf (&op->esil, "0x%02x,sp,+=", data);
|
||||
@ -171,17 +171,17 @@ static inline void gb_anal_add_sp(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
r_strbuf_append (&op->esil, ",0,Z,=,0,N,:=");
|
||||
}
|
||||
|
||||
static void gb_anal_mov_imm(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
static void gb_anal_mov_imm(RAnalOp *op, const ut8 *data) {
|
||||
RAnalValue *dst = r_vector_push (&op->dsts, NULL);
|
||||
RAnalValue *src = r_vector_push (&op->srcs, NULL);
|
||||
if (data[0] & 1) {
|
||||
dst->reg = r_reg_get (reg, regs_16[data[0]>>4], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_16[data[0]>>4];
|
||||
dst->type = R_ANAL_VAL_REG;
|
||||
src->imm = GB_SOFTCAST (data[1], data[2]);
|
||||
src->type = R_ANAL_VAL_IMM;
|
||||
r_strbuf_setf (&op->esil, "0x%04" PFMT64x ",%s,=", src->imm, regs_16[data[0]>>4]);
|
||||
} else {
|
||||
dst->reg = r_reg_get (reg, regs_8[data[0]>>3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_8[data[0]>>3];
|
||||
dst->type = R_ANAL_VAL_REG;
|
||||
src->imm = data[1];
|
||||
src->type = R_ANAL_VAL_IMM;
|
||||
@ -195,8 +195,8 @@ static inline void gb_anal_mov_sp_hl(RReg *reg, RAnalOp *op) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "sp", R_REG_TYPE_GPR);
|
||||
src->reg = r_reg_get (reg, "hl", R_REG_TYPE_GPR);
|
||||
dst->reg = "sp";
|
||||
src->reg = "hl";
|
||||
r_strbuf_set (&op->esil, "hl,sp,=");
|
||||
}
|
||||
|
||||
@ -205,8 +205,8 @@ static inline void gb_anal_mov_hl_sp(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src0 = r_vector_push (&op->srcs, NULL);
|
||||
src1 = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, regs_16[2], R_REG_TYPE_GPR);
|
||||
src0->reg = r_reg_get (reg, regs_16[3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_16[2];
|
||||
src0->reg = regs_16[3];
|
||||
src1->imm = (st8)data;
|
||||
src1->type = R_ANAL_VAL_IMM;
|
||||
if (data < 128) {
|
||||
@ -221,8 +221,8 @@ static void gb_anal_mov_reg(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, regs_8[(data/8) - 8], R_REG_TYPE_GPR);
|
||||
src->reg = r_reg_get (reg, regs_8[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_8[(data/8) - 8];
|
||||
src->reg = regs_8[data & 7];
|
||||
r_strbuf_setf (&op->esil, "%s,%s,=", regs_8[data & 7], regs_8[(data/8) - 8]);
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ static inline void gb_anal_mov_ime(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "ime", R_REG_TYPE_GPR);
|
||||
dst->reg = "ime";
|
||||
src->absolute = true;
|
||||
src->imm = (data != 0xf3);
|
||||
r_strbuf_setf (&op->esil, "%d,ime,=", (int)src->imm);
|
||||
@ -243,7 +243,7 @@ static inline void gb_anal_mov_scf(RReg *reg, RAnalOp *op) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, regs_1[3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_1[3];
|
||||
src->imm = 1;
|
||||
r_strbuf_set (&op->esil, "1,C,:=");
|
||||
}
|
||||
@ -252,7 +252,7 @@ static inline void gb_anal_xor_cpl(RReg *reg, RAnalOp *op) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, regs_8[7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_8[7];
|
||||
src->imm = 0xff;
|
||||
r_strbuf_set (&op->esil, "0xff,a,^=,1,N,:=,1,H,:=");
|
||||
}
|
||||
@ -261,7 +261,7 @@ static inline void gb_anal_xor_ccf(RReg *reg, RAnalOp *op) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, regs_1[3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_1[3];
|
||||
src->imm = 1;
|
||||
r_strbuf_set (&op->esil, "C,!=");
|
||||
}
|
||||
@ -285,16 +285,16 @@ static inline void gb_anal_cond(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
case 0xc8:
|
||||
case 0xca:
|
||||
case 0xcc:
|
||||
dst->reg = r_reg_get (reg, regs_1[0], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_1[0];
|
||||
break;
|
||||
default:
|
||||
dst->reg = r_reg_get (reg, regs_1[3], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_1[3];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gb_anal_pp(RReg *reg, RAnalOp *op, const ut8 data) {//push , pop
|
||||
RAnalValue val = {0};
|
||||
val.reg = r_reg_get (reg, regs_16_alt[(data>>4) - 12], R_REG_TYPE_GPR);
|
||||
val.reg = regs_16_alt[(data>>4) - 12];
|
||||
if ((data & 0xf) == 1) {
|
||||
r_vector_push (&op->dsts, &val);
|
||||
r_strbuf_setf (&op->esil, "sp,[2],%s,=,2,sp,+=", regs_16_alt[(data>>4) - 12]); //pop
|
||||
@ -310,7 +310,7 @@ static inline void gb_anal_and_res(RAnal *anal, RAnalOp *op, const ut8 data) {
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = ((~(0x1 << ((data >> 3) & 7))) & 0xff);
|
||||
dst->memref = ((data & 7) == 6);
|
||||
dst->reg = r_reg_get (anal->reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "0x%02" PFMT64x ",%s,[1],&,%s,=[1]", src->imm, regs_x[data & 7], regs_x[data & 7]);
|
||||
} else {
|
||||
@ -324,7 +324,7 @@ static inline void gb_anal_and_bit(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1<<((data>>3) & 7);
|
||||
dst->memref = ((data & 7) == 6);
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "%" PFMT64d ",%s,[1],&,0,==,$z,Z,:=,0,N,:=,1,H,:=", src->imm, regs_x[data & 7]);
|
||||
} else {
|
||||
@ -338,7 +338,7 @@ static inline void gb_anal_or_set(RAnal *anal, RAnalOp *op, const ut8 data) {
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = (data>>3) & 7;
|
||||
dst->memref = ((data & 7) == 6);
|
||||
dst->reg = r_reg_get (anal->reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "0x%02" PFMT64x ",%s,[1],|,%s,=[1]", src->imm, regs_x[data & 7], regs_x[data & 7]);
|
||||
} else {
|
||||
@ -351,8 +351,8 @@ static void gb_anal_xoaasc(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src0 = r_vector_push (&op->srcs, NULL);
|
||||
src1 = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "a", R_REG_TYPE_GPR);
|
||||
src0->reg = r_reg_get (reg, regs_x[data[0] & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = "a";
|
||||
src0->reg = regs_x[data[0] & 7];
|
||||
src0->memref = ((data[0] & 7) == 6);
|
||||
switch (op->type) {
|
||||
case R_ANAL_OP_TYPE_XOR:
|
||||
@ -379,14 +379,14 @@ static void gb_anal_xoaasc(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
case R_ANAL_OP_TYPE_ADD:
|
||||
if (src0->memref) {
|
||||
if (data[0] > 0x87) {
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_setf (&op->esil, "C,%s,[1],+,a,+=,$z,Z,:=,3,$c,H,:=,7,$c,C,:=,0,N,:=", regs_x[data[0] & 7]);
|
||||
} else {
|
||||
r_strbuf_setf (&op->esil, "%s,[1],a,+=,$z,Z,:=,3,$c,H,:=,7,$c,C,:=,0,N,:=", regs_x[data[0] & 7]);
|
||||
}
|
||||
} else {
|
||||
if (data[0] > 0x87) {
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_setf (&op->esil, "C,%s,+,a,+=,$z,Z,:=,3,$c,H,:=,7,$c,C,:=,0,N,:=", regs_x[data[0] & 7]);
|
||||
} else {
|
||||
r_strbuf_setf (&op->esil, "%s,a,+=,$z,Z,:=,3,$c,H,:=,7,$c,C,:=,0,N,:=", regs_x[data[0] & 7]);
|
||||
@ -396,14 +396,14 @@ static void gb_anal_xoaasc(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
case R_ANAL_OP_TYPE_SUB:
|
||||
if (src0->memref) {
|
||||
if (data[0] > 0x97) {
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_setf (&op->esil, "C,%s,[1],+,a,-=,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", regs_x[data[0] & 7]);
|
||||
} else {
|
||||
r_strbuf_setf (&op->esil, "%s,[1],a,-=,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", regs_x[data[0] & 7]);
|
||||
}
|
||||
} else {
|
||||
if (data[0] > 0x97) {
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_setf (&op->esil, "C,%s,+,a,-=,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", regs_x[data[0] & 7]);
|
||||
} else {
|
||||
r_strbuf_setf (&op->esil, "%s,a,-=,$z,Z,:=,4,$b,H,:=,8,$b,C,:=,1,N,:=", regs_x[data[0] & 7]);
|
||||
@ -429,7 +429,7 @@ static void gb_anal_xoaasc_imm(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src0 = r_vector_push (&op->srcs, NULL);
|
||||
src1 = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "a", R_REG_TYPE_GPR);
|
||||
dst->reg = "a";
|
||||
src0->absolute = true;
|
||||
src0->imm = data[1];
|
||||
src0->type = R_ANAL_VAL_IMM;
|
||||
@ -446,7 +446,7 @@ static void gb_anal_xoaasc_imm(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
case R_ANAL_OP_TYPE_ADD:
|
||||
r_strbuf_setf (&op->esil, "0x%02x,", data[1]);
|
||||
if (data[0] == 0xce) { //adc
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_append (&op->esil, "a,+=,C,NUM,7,$c,C,:=,3,$c,H,:=,a,+=,7,$c,C,|,C,:=,3,$c,H,|=,a,a,=,$z,Z,:=,0,N,:=");
|
||||
} else {
|
||||
r_strbuf_append (&op->esil, "a,+=,3,$c,H,:=,7,$c,C,:=,0,N,:=,a,a,=,$z,Z,:=");
|
||||
@ -455,7 +455,7 @@ static void gb_anal_xoaasc_imm(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
case R_ANAL_OP_TYPE_SUB:
|
||||
r_strbuf_setf (&op->esil, "0x%02x,", data[1]);
|
||||
if (data[0] == 0xde) { //sbc
|
||||
src1->reg = r_reg_get (reg, "C", R_REG_TYPE_GPR);
|
||||
src1->reg = "C";
|
||||
r_strbuf_append (&op->esil, "a,-=,C,NUM,8,$b,C,:=,4,$b,H,:=,a,-=,8,$b,C,|,C,=,4,$b,H,|,H,=,a,a,=,$z,Z,:=,1,N,:=");
|
||||
} else {
|
||||
r_strbuf_append (&op->esil, "a,-=,4,$b,H,:=,8,$b,C,:=,1,N,:=,a,a,=,$z,Z,:=");
|
||||
@ -471,10 +471,10 @@ static void gb_anal_xoaasc_imm(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
static inline void gb_anal_load_hl(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
RAnalValue *dst = r_vector_push (&op->dsts, NULL);
|
||||
RAnalValue *src = r_vector_push (&op->srcs, NULL);
|
||||
src->reg = r_reg_get (reg, "hl", R_REG_TYPE_GPR);
|
||||
src->reg = "hl";
|
||||
src->memref = 1;
|
||||
src->absolute = true;
|
||||
dst->reg = r_reg_get (reg, regs_8[((data & 0x38)>>3)], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_8[((data & 0x38) >> 3)];
|
||||
r_strbuf_setf (&op->esil, "hl,[1],%s,=", regs_8[((data & 0x38)>>3)]);
|
||||
if (data == 0x3a) {
|
||||
r_strbuf_append (&op->esil, ",1,hl,-=");
|
||||
@ -488,7 +488,7 @@ static inline void gb_anal_load(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "a", R_REG_TYPE_GPR);
|
||||
dst->reg = "a";
|
||||
src->memref = 1;
|
||||
switch (data[0]) {
|
||||
case 0xf0:
|
||||
@ -497,7 +497,7 @@ static inline void gb_anal_load(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
break;
|
||||
case 0xf2:
|
||||
src->base = 0xff00;
|
||||
src->regdelta = r_reg_get (reg, "c", R_REG_TYPE_GPR);
|
||||
src->regdelta = "c";
|
||||
r_strbuf_set (&op->esil, "0xff00,c,+,[1],a,=");
|
||||
break;
|
||||
case 0xfa:
|
||||
@ -512,7 +512,7 @@ static inline void gb_anal_load(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
r_strbuf_setf (&op->esil, "0x%04" PFMT64x ",[1],a,=", src->base);
|
||||
break;
|
||||
default:
|
||||
src->reg = r_reg_get (reg, regs_16[(data[0] & 0xf0) >> 4], R_REG_TYPE_GPR);
|
||||
src->reg = regs_16[(data[0] & 0xf0) >> 4];
|
||||
r_strbuf_setf (&op->esil, "%s,[1],a,=", regs_16[(data[0] & 0xf0) >> 4]);
|
||||
break;
|
||||
}
|
||||
@ -522,14 +522,14 @@ static inline void gb_anal_store_hl(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
RAnalValue *dst, *src;
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->reg = r_reg_get (reg, "hl", R_REG_TYPE_GPR);
|
||||
dst->reg = "hl";
|
||||
dst->memref = 1;
|
||||
src->absolute = true;
|
||||
if (data[0] == 0x36) {
|
||||
src->imm = data[1];
|
||||
r_strbuf_setf (&op->esil, "0x%02x,hl,=[1]", data[1]);
|
||||
} else {
|
||||
src->reg = r_reg_get (reg, regs_8[data[0] & 0x07], R_REG_TYPE_GPR);
|
||||
src->reg = regs_8[data[0] & 0x07];
|
||||
r_strbuf_setf (&op->esil, "%s,hl,=[1]", regs_8[data[0] & 0x07]);
|
||||
}
|
||||
if (data[0] == 0x32) {
|
||||
@ -545,12 +545,12 @@ static void gb_anal_store(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
dst->memref = 1;
|
||||
src->reg = r_reg_get (reg, "a", R_REG_TYPE_GPR);
|
||||
src->reg = "a";
|
||||
switch (data[0]) {
|
||||
case 0x08:
|
||||
dst->memref = 2;
|
||||
dst->base = GB_SOFTCAST (data[1], data[2]);
|
||||
src->reg = r_reg_get (reg, "sp", R_REG_TYPE_GPR);
|
||||
src->reg = "sp";
|
||||
r_strbuf_setf (&op->esil, "sp,0x%04" PFMT64x ",=[2]", dst->base);
|
||||
break;
|
||||
case 0xe0:
|
||||
@ -559,7 +559,7 @@ static void gb_anal_store(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
break;
|
||||
case 0xe2:
|
||||
dst->base = 0xff00;
|
||||
dst->regdelta = r_reg_get (reg, "c", R_REG_TYPE_GPR);
|
||||
dst->regdelta = "c";
|
||||
r_strbuf_set (&op->esil, "a,0xff00,c,+,=[1]");
|
||||
break;
|
||||
case 0xea:
|
||||
@ -567,7 +567,7 @@ static void gb_anal_store(RReg *reg, RAnalOp *op, const ut8 *data) {
|
||||
r_strbuf_setf (&op->esil, "a,0x%04" PFMT64x ",=[1]", dst->base);
|
||||
break;
|
||||
default:
|
||||
dst->reg = r_reg_get (reg, regs_16[(data[0] & 0xf0)>>4], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_16[(data[0] & 0xf0)>>4];
|
||||
r_strbuf_setf (&op->esil , "a,%s,=[1]", regs_16[(data[0] & 0xf0)>>4]);
|
||||
}
|
||||
}
|
||||
@ -577,7 +577,7 @@ static inline void gb_anal_cb_swap(RReg *reg, RAnalOp* op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 4;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if ((data & 7) == 6) {
|
||||
dst->memref = 1;
|
||||
r_strbuf_setf (&op->esil, "4,%s,[1],>>,4,%s,[1],<<,|,%s,=[1],$z,Z,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -591,7 +591,7 @@ static inline void gb_anal_cb_rlc(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if ((data & 7) == 6) {
|
||||
dst->memref = 1;
|
||||
r_strbuf_setf (&op->esil, "7,%s,[1],>>,1,&,C,:=,1,%s,[1],<<,C,|,%s,=[1],$z,Z,:=,0,H,:=,0,N,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -605,7 +605,7 @@ static inline void gb_anal_cb_rl(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if ((data & 7) == 6) {
|
||||
dst->memref = 1;
|
||||
r_strbuf_setf (&op->esil, "1,%s,<<,C,|,%s,=[1],7,$c,C,:=,$z,Z,:=,0,H,:=,0,N,:=", regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -619,7 +619,7 @@ static inline void gb_anal_cb_rrc(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get(reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if ((data &7) == 6) {
|
||||
dst->memref = 1;
|
||||
r_strbuf_setf (&op->esil, "1,%s,[1],&,C,:=,1,%s,[1],>>,7,C,<<,|,%s,=[1],$z,Z,:=,0,H,:=,0,N,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -633,7 +633,7 @@ static inline void gb_anal_cb_rr(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
if ((data & 7) == 6) {
|
||||
dst->memref = 1;
|
||||
r_strbuf_setf (&op->esil, "1,%s,[1],&,H,:=,1,%s,[1],>>,7,C,<<,|,%s,=[1],H,C,:=,0,H,:=,0,N,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -648,7 +648,7 @@ static inline void gb_anal_cb_sla(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
dst->memref = ((data & 7) == 6);
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "1,%s,[1],<<,%s,=[1],7,$c,C,:=,%s,[1],%s,=[1],$z,Z,:=,0,H,:=,0,N,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -662,7 +662,7 @@ static inline void gb_anal_cb_sra(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
dst->memref = ((data & 7) == 6);
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "1,%s,[1],&,C,:=,0x80,%s,[1],&,1,%s,[1],>>,|,%s,=[1],$z,Z,:=,0,N,:=,0,H,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]); //spaguesil
|
||||
@ -676,7 +676,7 @@ static inline void gb_anal_cb_srl(RReg *reg, RAnalOp *op, const ut8 data) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->imm = 1;
|
||||
dst->reg = r_reg_get (reg, regs_x[data & 7], R_REG_TYPE_GPR);
|
||||
dst->reg = regs_x[data & 7];
|
||||
dst->memref = ((data & 7) == 6);
|
||||
if (dst->memref) {
|
||||
r_strbuf_setf (&op->esil, "1,%s,[1],&,C,:=,1,%s,[1],>>,%s,=[1],$z,Z,:=,0,N,:=,0,H,:=", regs_x[data & 7], regs_x[data & 7], regs_x[data & 7]);
|
||||
@ -749,7 +749,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
|
||||
case 0x11:
|
||||
case 0x21:
|
||||
case 0x31:
|
||||
gb_anal_mov_imm (anal->reg, op, data);
|
||||
gb_anal_mov_imm (op, data);
|
||||
op->cycles = 12;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
break;
|
||||
@ -766,7 +766,7 @@ static int gb_anop(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len
|
||||
case 0x26:
|
||||
case 0x2e:
|
||||
case 0x3e:
|
||||
gb_anal_mov_imm (anal->reg, op, data);
|
||||
gb_anal_mov_imm (op, data);
|
||||
op->cycles = 8;
|
||||
op->type = R_ANAL_OP_TYPE_MOV;
|
||||
break;
|
||||
@ -1538,14 +1538,14 @@ static int esil_gb_init(REsil *esil) {
|
||||
esil->anal->iob.read_at (esil->anal->iob.io, 0x147, &user->mbc_id, 1);
|
||||
esil->anal->iob.read_at (esil->anal->iob.io, 0x148, &user->romsz_id, 1);
|
||||
esil->anal->iob.read_at (esil->anal->iob.io, 0x149, &user->ramsz_id, 1);
|
||||
if (esil->anal->reg) { //initial values
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "mpc", -1), 0x100);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "sp", -1), 0xfffe);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "af", -1), 0x01b0);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "bc", -1), 0x0013);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "de", -1), 0x00d8);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "hl", -1), 0x014d);
|
||||
r_reg_set_value (esil->anal->reg, r_reg_get (esil->anal->reg, "ime", -1), true);
|
||||
if (esil->anal->reg) { //initial values
|
||||
r_reg_setv (esil->anal->reg, "mpc", 0x100);
|
||||
r_reg_setv (esil->anal->reg, "sp", 0xfffe);
|
||||
r_reg_setv (esil->anal->reg, "af", 0x01b0);
|
||||
r_reg_setv (esil->anal->reg, "bc", 0x0013);
|
||||
r_reg_setv (esil->anal->reg, "de", 0x00d8);
|
||||
r_reg_setv (esil->anal->reg, "hl", 0x014d);
|
||||
r_reg_setv (esil->anal->reg, "ime", true);
|
||||
}
|
||||
}
|
||||
esil->cb.user = user;
|
||||
|
@ -35,21 +35,21 @@ static R_TH_LOCAL ut64 t9_pre = UT64_MAX;
|
||||
dst = r_vector_push (&(op)->dsts, NULL);
|
||||
|
||||
#define SET_SRC_DST_3_REGS(op) \
|
||||
CREATE_SRC_DST_3 (op);\
|
||||
dst->reg = r_reg_get (anal->reg, REG (0), R_REG_TYPE_GPR);\
|
||||
src0->reg = r_reg_get (anal->reg, REG (1), R_REG_TYPE_GPR);\
|
||||
src1->reg = r_reg_get (anal->reg, REG (2), R_REG_TYPE_GPR);
|
||||
CREATE_SRC_DST_3 (op); \
|
||||
dst->reg = REG (0); \
|
||||
src0->reg = REG (1); \
|
||||
src1->reg = REG (2);
|
||||
|
||||
#define SET_SRC_DST_3_IMM(op) \
|
||||
CREATE_SRC_DST_3 (op);\
|
||||
dst->reg = r_reg_get (anal->reg, REG (0), R_REG_TYPE_GPR);\
|
||||
src0->reg = r_reg_get (anal->reg, REG (1), R_REG_TYPE_GPR);\
|
||||
dst->reg = REG (0);\
|
||||
src0->reg = REG (1);\
|
||||
src1->imm = IMM (2);
|
||||
|
||||
#define SET_SRC_DST_2_REGS(op) \
|
||||
CREATE_SRC_DST_2 (op);\
|
||||
dst->reg = r_reg_get (anal->reg, REG (0), R_REG_TYPE_GPR);\
|
||||
src0->reg = r_reg_get (anal->reg, REG (1), R_REG_TYPE_GPR);
|
||||
dst->reg = REG (0);\
|
||||
src0->reg = REG (1);
|
||||
|
||||
#define SET_SRC_DST_3_REG_OR_IMM(op) \
|
||||
if (OPERAND(2).type == MIPS_OP_IMM) {\
|
||||
@ -135,8 +135,11 @@ static void opex(RStrBuf *buf, csh handle, cs_insn *insn) {
|
||||
pj_o (pj);
|
||||
switch (op->type) {
|
||||
case MIPS_OP_REG:
|
||||
pj_ks (pj, "type", "reg");
|
||||
pj_ks (pj, "value", cs_reg_name (handle, op->reg));
|
||||
{
|
||||
const char *rn = cs_reg_name (handle, op->reg);
|
||||
pj_ks (pj, "type", "reg");
|
||||
pj_ks (pj, "value", rn? rn: "");
|
||||
}
|
||||
break;
|
||||
case MIPS_OP_IMM:
|
||||
pj_ks (pj, "type", "imm");
|
||||
@ -668,43 +671,34 @@ static int analop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_reg_name(RRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
|
||||
if (!reg) {
|
||||
return -1;
|
||||
}
|
||||
static const char *parse_reg_name(csh handle, cs_insn *insn, int reg_num) {
|
||||
switch (OPERAND (reg_num).type) {
|
||||
case MIPS_OP_REG:
|
||||
reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).reg);
|
||||
break;
|
||||
return cs_reg_name (handle, OPERAND (reg_num).reg);
|
||||
case MIPS_OP_MEM:
|
||||
if (OPERAND (reg_num).mem.base != MIPS_REG_INVALID) {
|
||||
reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).mem.base);
|
||||
return cs_reg_name (handle, OPERAND (reg_num).mem.base);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void op_fillval(RAnal *anal, RAnalOp *op, csh *handle, cs_insn *insn) {
|
||||
static R_TH_LOCAL RRegItem reg = {0};
|
||||
RAnalValue *dst, *src0, *src1;
|
||||
switch (op->type & R_ANAL_OP_TYPE_MASK) {
|
||||
case R_ANAL_OP_TYPE_LOAD:
|
||||
if (OPERAND(1).type == MIPS_OP_MEM) {
|
||||
ZERO_FILL (reg);
|
||||
src0 = r_vector_push (&op->srcs, NULL);
|
||||
src0->reg = ®
|
||||
parse_reg_name (src0->reg, *handle, insn, 1);
|
||||
src0->reg = parse_reg_name (*handle, insn, 1);
|
||||
src0->delta = OPERAND(1).mem.disp;
|
||||
}
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_STORE:
|
||||
if (OPERAND(1).type == MIPS_OP_MEM) {
|
||||
ZERO_FILL (reg);
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
dst->reg = ®
|
||||
parse_reg_name (dst->reg, *handle, insn, 1);
|
||||
dst->reg = parse_reg_name (*handle, insn, 1);
|
||||
dst->delta = OPERAND(1).mem.disp;
|
||||
}
|
||||
break;
|
||||
|
@ -49,6 +49,7 @@ struct Getarg {
|
||||
int bits;
|
||||
};
|
||||
|
||||
// TODO: get rid of this unnecessary wrapper
|
||||
static void hidden_op(cs_insn *insn, cs_x86 *x, int mode) {
|
||||
unsigned int id = insn->id;
|
||||
int regsz = 4;
|
||||
@ -242,10 +243,16 @@ static char *getarg(struct Getarg* gop, int n, int set, char *setop, ut32 *bitsi
|
||||
case X86_OP_INVALID:
|
||||
return strdup ("invalid");
|
||||
case X86_OP_REG:
|
||||
if (set == 1) {
|
||||
return r_str_newf ("%s,%s=", cs_reg_name (handle, op.reg), setarg);
|
||||
{
|
||||
const char *rn = cs_reg_name (handle, op.reg);
|
||||
if (rn) {
|
||||
if (set == 1) {
|
||||
return r_str_newf ("%s,%s=", rn, setarg);
|
||||
}
|
||||
return strdup (rn);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return strdup (cs_reg_name (handle, op.reg));
|
||||
case X86_OP_IMM:
|
||||
if (set == 1) {
|
||||
return r_str_newf ("%"PFMT64u",%s=[%d]", (ut64)op.imm, setarg, op.size);
|
||||
@ -351,7 +358,7 @@ static const char *reg32_to_name(ut8 reg) {
|
||||
return reg < R_ARRAY_SIZE (names) ? names[reg] : "unk";
|
||||
}
|
||||
|
||||
static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) {
|
||||
static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, csh handle, cs_insn *insn) {
|
||||
RAnalValue *val = NULL;
|
||||
const int bits = a->config->bits;
|
||||
int rs = bits / 8;
|
||||
@ -378,7 +385,7 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
break;
|
||||
}
|
||||
struct Getarg gop = {
|
||||
.handle = *handle,
|
||||
.handle = handle,
|
||||
.insn = insn,
|
||||
.bits = bits
|
||||
};
|
||||
@ -714,8 +721,8 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
case X86_INS_MOVSW:
|
||||
if (op->prefix & R_ANAL_OP_PREFIX_REP) {
|
||||
int width = INSOP(0).size;
|
||||
src = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
|
||||
dst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
|
||||
src = (char *)cs_reg_name (handle, INSOP(1).mem.base);
|
||||
dst = (char *)cs_reg_name (handle, INSOP(0).mem.base);
|
||||
r_strbuf_appendf (&op->esil,
|
||||
"%s,[%d],%s,=[%d],"\
|
||||
"df,?{,%d,%s,-=,%d,%s,-=,},"\
|
||||
@ -725,8 +732,8 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
width, src, width, dst);
|
||||
} else {
|
||||
int width = INSOP(0).size;
|
||||
src = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
|
||||
dst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
|
||||
src = (char *)cs_reg_name (handle, INSOP(1).mem.base);
|
||||
dst = (char *)cs_reg_name (handle, INSOP(0).mem.base);
|
||||
esilprintf (op, "%s,[%d],%s,=[%d],df,?{,%d,%s,-=,%d,%s,-=,},"\
|
||||
"df,!,?{,%d,%s,+=,%d,%s,+=,}",
|
||||
src, width, dst, width, width, src, width,
|
||||
@ -757,8 +764,8 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
case X86_OP_MEM:
|
||||
if (op->prefix & R_ANAL_OP_PREFIX_REP) {
|
||||
int width = INSOP (0).size;
|
||||
const char *src = cs_reg_name (*handle, INSOP (1).mem.base);
|
||||
const char *dst = cs_reg_name (*handle, INSOP (0).mem.base);
|
||||
const char *src = cs_reg_name (handle, INSOP (1).mem.base);
|
||||
const char *dst = cs_reg_name (handle, INSOP (0).mem.base);
|
||||
const char *counter = (bits == 16)?"cx": (bits==32)?"ecx":"rcx";
|
||||
esilprintf (op, "%s,!,?{,BREAK,},%s,NUM,%s,NUM,"\
|
||||
"%s,[%d],%s,=[%d],df,?{,%d,%s,-=,%d,%s,-=,},"\
|
||||
@ -782,7 +789,7 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
}
|
||||
if (INSOP(1).type == X86_OP_MEM) {
|
||||
// MOV REG, [PTR + IREG*SCALE]
|
||||
op->ireg = cs_reg_name (*handle, INSOP (1).mem.index);
|
||||
op->ireg = cs_reg_name (handle, INSOP (1).mem.index);
|
||||
op->disp = INSOP (1).mem.disp;
|
||||
op->scale = INSOP (1).mem.scale;
|
||||
}
|
||||
@ -1098,8 +1105,8 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
"%s,0x%"PFMT64x",-,!,%u,$o,^,of,:=,3,$b,af,:=",
|
||||
src, dst, bitsize, bitsize - 1, src, (ut64)(1ULL << (bitsize - 1)), bitsize - 1);
|
||||
} else {
|
||||
char *rsrc = (char *)cs_reg_name(*handle, INSOP(1).mem.base);
|
||||
char *rdst = (char *)cs_reg_name(*handle, INSOP(0).mem.base);
|
||||
char *rsrc = (char *)cs_reg_name (handle, INSOP(1).mem.base);
|
||||
char *rdst = (char *)cs_reg_name (handle, INSOP(0).mem.base);
|
||||
const int width = INSOP(0).size;
|
||||
esilprintf (op,
|
||||
"%s,%s,==,$z,zf,:=,%u,$b,cf,:=,$p,pf,:=,%u,$s,sf,:=,%s,0x%"PFMT64x","\
|
||||
@ -1522,12 +1529,18 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
}
|
||||
break;
|
||||
case X86_OP_REG:
|
||||
#if 0
|
||||
{
|
||||
src = getarg (&gop, 0, 0, NULL, NULL);
|
||||
val = r_vector_push (&op->srcs, NULL);
|
||||
val->reg = r_reg_get (a->reg, src, R_REG_TYPE_GPR);
|
||||
free (src);
|
||||
src = getarg (&gop, 0, 0, NULL, NULL);
|
||||
val = r_vector_push (&op->srcs, NULL);
|
||||
val->reg = r_reg_get (a->reg, src, R_REG_TYPE_GPR);
|
||||
free (src);
|
||||
}
|
||||
#else
|
||||
val = r_vector_push (&op->srcs, NULL);
|
||||
val->reg = cs_reg_name (handle, INSOP (0).reg);
|
||||
#endif
|
||||
break;
|
||||
//case X86_OP_FP:
|
||||
default: // other?
|
||||
break;
|
||||
@ -2378,16 +2391,7 @@ static void anop_esil(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len,
|
||||
}
|
||||
}
|
||||
|
||||
// R2_590 - return const char * to avoid derefs
|
||||
static RRegItem *cs_reg2reg(RReg *reg, csh *h, int id) {
|
||||
if (id == X86_REG_INVALID) {
|
||||
return NULL;
|
||||
}
|
||||
RRegItem *ri = r_reg_get (reg, (char *)cs_reg_name (*h, id), -1);
|
||||
return ri;
|
||||
}
|
||||
|
||||
static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn, int mode) {
|
||||
static void set_access_info(RReg *reg, RAnalOp *op, csh handle, cs_insn *insn, int mode) {
|
||||
int i;
|
||||
int regsz;
|
||||
x86_reg sp;
|
||||
@ -2419,7 +2423,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_REG;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, X86_REG_RIP);
|
||||
val->reg = cs_reg_name (handle, X86_REG_RIP);
|
||||
r_list_append (ret, val);
|
||||
}
|
||||
|
||||
@ -2427,13 +2431,13 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
// Register access info
|
||||
cs_regs regs_read, regs_write;
|
||||
ut8 read_count, write_count;
|
||||
if (cs_regs_access (*handle, insn, regs_read, &read_count, regs_write, &write_count) == 0) {
|
||||
if (cs_regs_access (handle, insn, regs_read, &read_count, regs_write, &write_count) == 0) {
|
||||
for (i = 0; i < read_count; i++) {
|
||||
val = r_anal_value_new ();
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_REG;
|
||||
val->access = R_PERM_R;
|
||||
val->reg = cs_reg2reg (reg, handle, regs_read[i]);
|
||||
val->reg = cs_reg_name (handle, regs_read[i]);
|
||||
r_list_append (ret, val);
|
||||
}
|
||||
}
|
||||
@ -2442,7 +2446,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_REG;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, regs_write[i]);
|
||||
val->reg = cs_reg_name (handle, regs_write[i]);
|
||||
r_list_append (ret, val);
|
||||
}
|
||||
}
|
||||
@ -2455,7 +2459,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -INSOP(0).size;
|
||||
val->memref = INSOP(0).size;
|
||||
r_list_append (ret, val);
|
||||
@ -2467,7 +2471,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -16;
|
||||
val->memref = 16;
|
||||
r_list_append (ret, val);
|
||||
@ -2479,7 +2483,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -32;
|
||||
val->memref = 32;
|
||||
r_list_append (ret, val);
|
||||
@ -2490,7 +2494,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -2;
|
||||
val->memref = 2;
|
||||
r_list_append (ret, val);
|
||||
@ -2501,7 +2505,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -4;
|
||||
val->memref = 4;
|
||||
r_list_append (ret, val);
|
||||
@ -2512,7 +2516,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -8;
|
||||
val->memref = 8;
|
||||
r_list_append (ret, val);
|
||||
@ -2524,7 +2528,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
if (val) {
|
||||
val->type = R_ANAL_VAL_MEM;
|
||||
val->access = R_PERM_W;
|
||||
val->reg = cs_reg2reg (reg, handle, sp);
|
||||
val->reg = cs_reg_name (handle, sp);
|
||||
val->delta = -regsz;
|
||||
val->memref = regsz;
|
||||
r_list_append (ret, val);
|
||||
@ -2562,12 +2566,9 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
val->delta += insn->size;
|
||||
}
|
||||
val->memref = INSOP (i).size;
|
||||
r_unref (val->seg);
|
||||
val->seg = cs_reg2reg (reg, handle, INSOP (i).mem.segment);
|
||||
r_unref (val->reg);
|
||||
val->reg = cs_reg2reg (reg, handle, INSOP (i).mem.base);
|
||||
r_unref (val->regdelta);
|
||||
val->regdelta = cs_reg2reg (reg, handle, INSOP (i).mem.index);
|
||||
val->reg = cs_reg_name (handle, INSOP (i).mem.base);
|
||||
val->seg = cs_reg_name (handle, INSOP (i).mem.segment);
|
||||
val->regdelta = cs_reg_name (handle, INSOP (i).mem.index);
|
||||
r_list_append (ret, val);
|
||||
}
|
||||
}
|
||||
@ -2582,7 +2583,7 @@ static void set_access_info(RReg *reg, RAnalOp *op, csh *handle, cs_insn *insn,
|
||||
src2 = r_vector_push (&(op)->srcs, NULL); \
|
||||
dst = r_vector_push (&(op)->dsts, NULL);
|
||||
|
||||
static void set_src_dst(RReg *reg, RAnalValue *val, csh *handle, cs_insn *insn, int x) {
|
||||
static void set_src_dst(RReg *reg, RAnalValue *val, csh handle, cs_insn *insn, int x) {
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
@ -2591,16 +2592,12 @@ static void set_src_dst(RReg *reg, RAnalValue *val, csh *handle, cs_insn *insn,
|
||||
val->mul = INSOP (x).mem.scale;
|
||||
val->delta = INSOP (x).mem.disp;
|
||||
val->memref = INSOP (x).size;
|
||||
r_unref (val->seg);
|
||||
val->seg = cs_reg2reg (reg, handle, INSOP (x).mem.segment);
|
||||
r_unref (val->reg);
|
||||
val->reg = cs_reg2reg (reg, handle, INSOP (x).mem.base);
|
||||
r_unref (val->regdelta);
|
||||
val->regdelta = cs_reg2reg (reg, handle, INSOP (x).mem.index);
|
||||
val->seg = cs_reg_name (handle, INSOP (x).mem.segment);
|
||||
val->reg = cs_reg_name (handle, INSOP (x).mem.base);
|
||||
val->regdelta = cs_reg_name (handle, INSOP (x).mem.index);
|
||||
break;
|
||||
case X86_OP_REG:
|
||||
r_unref (val->reg);
|
||||
val->reg = cs_reg2reg (reg, handle, INSOP (x).reg);
|
||||
val->reg = cs_reg_name (handle, INSOP (x).reg);
|
||||
break;
|
||||
case X86_OP_IMM:
|
||||
val->imm = INSOP (x).imm;
|
||||
@ -2610,7 +2607,7 @@ static void set_src_dst(RReg *reg, RAnalValue *val, csh *handle, cs_insn *insn,
|
||||
}
|
||||
}
|
||||
|
||||
static void op_fillval(RAnal *a, RAnalOp *op, csh *handle, cs_insn *insn, int mode) {
|
||||
static void op_fillval(RAnal *a, RAnalOp *op, csh handle, cs_insn *insn, int mode) {
|
||||
RAnalValue *dst, *src0, *src1, *src2;
|
||||
set_access_info (a->reg, op, handle, insn, mode);
|
||||
switch (op->type & R_ANAL_OP_TYPE_MASK) {
|
||||
@ -3808,13 +3805,13 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAn
|
||||
anop (a, op, addr, buf, len, &handle, insn);
|
||||
set_opdir (op, insn);
|
||||
if (mask & R_ARCH_OP_MASK_ESIL) {
|
||||
anop_esil (a, op, addr, buf, len, &handle, insn);
|
||||
anop_esil (a, op, addr, buf, len, handle, insn);
|
||||
}
|
||||
if (mask & R_ARCH_OP_MASK_OPEX) {
|
||||
opex (a, &op->opex, insn, mode);
|
||||
}
|
||||
if (mask & R_ARCH_OP_MASK_VAL) {
|
||||
op_fillval (a, op, &handle, insn, mode);
|
||||
op_fillval (a, op, handle, insn, mode);
|
||||
}
|
||||
}
|
||||
//#if X86_GRP_PRIVILEGE>0
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2010-2020 - pancake */
|
||||
/* radare - LGPL - Copyright 2010-2023 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
|
||||
@ -19,10 +19,10 @@ R_API ut64 r_anal_value_to_ut64(RAnal *anal, RAnalValue *val) {
|
||||
}
|
||||
num = val->base + (val->delta * (val->mul ? val->mul : 1));
|
||||
if (val->reg) {
|
||||
num += r_reg_get_value (anal->reg, val->reg);
|
||||
num += r_reg_getv (anal->reg, val->reg);
|
||||
}
|
||||
if (val->regdelta) {
|
||||
num += r_reg_get_value (anal->reg, val->regdelta);
|
||||
num += r_reg_getv (anal->reg, val->regdelta);
|
||||
}
|
||||
switch (val->memref) {
|
||||
case 1:
|
||||
@ -49,21 +49,17 @@ R_API int r_anal_value_set_ut64(RAnal *anal, RAnalValue *val, ut64 num) {
|
||||
}
|
||||
} else {
|
||||
if (val->reg) {
|
||||
r_reg_set_value (anal->reg, val->reg, num);
|
||||
r_reg_setv (anal->reg, val->reg, num);
|
||||
}
|
||||
}
|
||||
return false; //is this necessary
|
||||
}
|
||||
|
||||
R_API const char *r_anal_value_type_tostring(RAnalValue *value) {
|
||||
if (value->type == R_ANAL_VAL_REG) {
|
||||
return "reg";
|
||||
}
|
||||
if (value->type == R_ANAL_VAL_MEM) {
|
||||
return "mem";
|
||||
}
|
||||
if (value->type == R_ANAL_VAL_IMM) {
|
||||
return "imm";
|
||||
switch (value->type) {
|
||||
case R_ANAL_VAL_REG: return "reg";
|
||||
case R_ANAL_VAL_MEM: return "mem";
|
||||
case R_ANAL_VAL_IMM: return "imm";
|
||||
}
|
||||
return "unk";
|
||||
}
|
||||
@ -92,10 +88,10 @@ R_API char *r_anal_value_tostring(RAnalValue *value) {
|
||||
out = r_str_appendf (out, "%d*", value->mul);
|
||||
}
|
||||
if (value->reg) {
|
||||
out = r_str_appendf (out, "%s", value->reg->name);
|
||||
out = r_str_appendf (out, "%s", value->reg);
|
||||
}
|
||||
if (value->regdelta) {
|
||||
out = r_str_appendf (out, "+%s", value->regdelta->name);
|
||||
out = r_str_appendf (out, "+%s", value->regdelta);
|
||||
}
|
||||
if (value->base != 0) {
|
||||
out = r_str_appendf (out, "0x%" PFMT64x, value->base);
|
||||
|
@ -9,7 +9,7 @@
|
||||
R_API bool r_anal_var_display(RAnal *anal, RAnalVar *var) {
|
||||
r_return_val_if_fail (anal && var, false);
|
||||
char *fmt = r_type_format (anal->sdb_types, var->type);
|
||||
RRegItem *i;
|
||||
RRegItem *ri;
|
||||
if (!fmt) {
|
||||
R_LOG_ERROR ("type:%s doesn't exist", var->type);
|
||||
return false;
|
||||
@ -17,12 +17,12 @@ R_API bool r_anal_var_display(RAnal *anal, RAnalVar *var) {
|
||||
bool usePxr = !strcmp (var->type, "int"); // hacky but useful
|
||||
switch (var->kind) {
|
||||
case R_ANAL_VAR_KIND_REG:
|
||||
i = r_reg_index_get (anal->reg, var->delta);
|
||||
if (i) {
|
||||
ri = r_reg_index_get (anal->reg, var->delta);
|
||||
if (ri) {
|
||||
if (usePxr) {
|
||||
anal->cb_printf ("pxr $w @r:%s\n", i->name);
|
||||
anal->cb_printf ("pxr $w @r:%s\n", ri->name);
|
||||
} else {
|
||||
anal->cb_printf ("pf r (%s)\n", i->name);
|
||||
anal->cb_printf ("pf r (%s)\n", ri->name);
|
||||
}
|
||||
} else {
|
||||
R_LOG_ERROR ("register not found");
|
||||
@ -854,19 +854,24 @@ static bool var_add_structure_fields_to_list(RAnal *a, RAnalVar *av, RList *list
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static const char *get_regname(RAnal *anal, RAnalValue *value) {
|
||||
return value? value->reg: NULL;
|
||||
}
|
||||
#else
|
||||
static const char *get_regname(RAnal *anal, RAnalValue *value) {
|
||||
// R2_590 - this is underperforming hard
|
||||
const char *name = NULL;
|
||||
if (value && value->reg && value->reg->name) {
|
||||
name = value->reg->name;
|
||||
RRegItem *ri = r_reg_get (anal->reg, value->reg->name, -1);
|
||||
if (value && value->reg) {
|
||||
name = value->reg;
|
||||
RRegItem *ri = r_reg_get (anal->reg, value->reg, -1);
|
||||
if (ri && (ri->size == 32) && (anal->config->bits == 64)) {
|
||||
name = r_reg_32_to_64 (anal->reg, value->reg->name);
|
||||
name = r_reg_32_to_64 (anal->reg, value->reg);
|
||||
}
|
||||
r_unref (ri);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
#endif
|
||||
|
||||
R_API R_OWN char *r_anal_function_autoname_var(RAnalFunction *fcn, char kind, const char *pfx, int ptr) {
|
||||
void **it;
|
||||
@ -912,8 +917,8 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
||||
r_return_if_fail (anal && fcn && op && reg);
|
||||
|
||||
r_vector_foreach (&op->srcs, val) {
|
||||
if (val && val->reg && val->reg->name) {
|
||||
if (!strcmp (reg, val->reg->name)) {
|
||||
if (val && val->reg) {
|
||||
if (!strcmp (reg, val->reg)) {
|
||||
st64 delta = val->delta;
|
||||
if ((delta > 0 && *sign == '+') || (delta < 0 && *sign == '-')) {
|
||||
ptr = R_ABS (val->delta);
|
||||
@ -949,7 +954,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
|
||||
if (!op->stackop && val) {
|
||||
const char *sp = r_reg_get_name (anal->reg, R_REG_NAME_SP);
|
||||
const char *bp = r_reg_get_name (anal->reg, R_REG_NAME_BP);
|
||||
const char *rn = (val && val->reg) ? val->reg->name : NULL;
|
||||
const char *rn = val? val->reg: NULL;
|
||||
if (rn && ((bp && !strcmp (bp, rn)) || (sp && !strcmp (sp, rn)))) {
|
||||
if (anal->verbose) {
|
||||
R_LOG_WARN ("Analysis didn't fill op->stackop for instruction that alters stack at 0x%" PFMT64x, op->addr);
|
||||
|
@ -97,7 +97,6 @@ R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name) {
|
||||
if (arch->session) {
|
||||
RArchPluginEncodeCallback encode = arch->session->plugin->encode;
|
||||
if (!encode) {
|
||||
#if R2_590
|
||||
RArchPlugin *ap = find_bestmatch (arch, config, name, true);
|
||||
if (ap) {
|
||||
RArchSession *es = r_arch_session (arch, config, ap);
|
||||
@ -107,7 +106,6 @@ R_API bool r_arch_use(RArch *arch, RArchConfig *config, const char *name) {
|
||||
arch->session->encoder = es;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
@ -242,12 +240,10 @@ R_API int r_arch_info(RArch *a, int query) {
|
||||
R_API bool r_arch_encode(RArch *a, RAnalOp *op, RArchEncodeMask mask) {
|
||||
RArchSession *session = a->session;
|
||||
RArchPluginEncodeCallback encode = R_UNWRAP3 (session, plugin, encode);
|
||||
#if R2_590
|
||||
if (!encode && session->encoder) {
|
||||
session = session->encoder;
|
||||
encode = R_UNWRAP3 (session, plugin, encode);
|
||||
}
|
||||
#endif
|
||||
return encode? encode (session, op, mask): false;
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,23 @@
|
||||
/* radare - LGPL - Copyright 2010-2022 - pancake, condret */
|
||||
/* radare - LGPL - Copyright 2010-2023 - pancake, condret */
|
||||
|
||||
#include <r_arch.h>
|
||||
#include <r_io.h>
|
||||
#include <r_reg.h>
|
||||
|
||||
R_API RArchValue *r_arch_value_new(void) { //macro for this ?
|
||||
return R_NEW0 (RArchValue);
|
||||
}
|
||||
|
||||
#if R2_590
|
||||
R_API RArchValue *r_arch_value_new_reg(const char * const reg) {
|
||||
RArchValue *v = R_NEW0 (RArchValue);
|
||||
v->reg = reg;
|
||||
if (v) {
|
||||
v->reg = reg;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: move into .h as #define free
|
||||
R_API void r_anal_value_free(RArchValue *value) {
|
||||
if (value) {
|
||||
r_unref (value->seg);
|
||||
r_unref (value->reg);
|
||||
r_unref (value->regdelta);
|
||||
free (value);
|
||||
}
|
||||
#if 0
|
||||
|
@ -204,23 +204,18 @@ static void opex(RStrBuf *buf, csh handle, cs_insn *insn) {
|
||||
pj_free (pj);
|
||||
}
|
||||
|
||||
static int parse_reg_name(RRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
|
||||
if (!reg) {
|
||||
return -1;
|
||||
}
|
||||
static const char *parse_reg_name(csh handle, cs_insn *insn, int reg_num) {
|
||||
switch (OPERAND (reg_num).type) {
|
||||
case M68K_OP_REG:
|
||||
reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).reg);
|
||||
break;
|
||||
return (char *)cs_reg_name (handle, OPERAND (reg_num).reg);
|
||||
case M68K_OP_MEM:
|
||||
if (OPERAND (reg_num).mem.base_reg != M68K_REG_INVALID) {
|
||||
reg->name = (char *)cs_reg_name (handle, OPERAND (reg_num).mem.base_reg);
|
||||
return (char *)cs_reg_name (handle, OPERAND (reg_num).mem.base_reg);
|
||||
}
|
||||
break;
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void op_fillval(PluginData *pd, RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
@ -230,13 +225,11 @@ static void op_fillval(PluginData *pd, RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
ZERO_FILL (pd->reg);
|
||||
if (OPERAND(1).type == M68K_OP_MEM) {
|
||||
src = r_vector_push (&op->srcs, NULL);
|
||||
src->reg = &pd->reg;
|
||||
parse_reg_name (src->reg, handle, insn, 1);
|
||||
src->reg = parse_reg_name (handle, insn, 1);
|
||||
src->delta = OPERAND(0).mem.disp;
|
||||
} else if (OPERAND(0).type == M68K_OP_MEM) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
dst->reg = &pd->reg;
|
||||
parse_reg_name (dst->reg, handle, insn, 0);
|
||||
dst->reg = parse_reg_name (handle, insn, 0);
|
||||
dst->delta = OPERAND(1).mem.disp;
|
||||
}
|
||||
break;
|
||||
@ -244,8 +237,7 @@ static void op_fillval(PluginData *pd, RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
ZERO_FILL (pd->reg);
|
||||
if (OPERAND(1).type == M68K_OP_MEM) {
|
||||
dst = r_vector_push (&op->dsts, NULL);
|
||||
dst->reg = &pd->reg;
|
||||
parse_reg_name (dst->reg, handle, insn, 1);
|
||||
dst->reg = parse_reg_name (handle, insn, 1);
|
||||
dst->delta = OPERAND(1).mem.disp;
|
||||
}
|
||||
break;
|
||||
|
@ -433,41 +433,31 @@ static int analop_vle(RArchSession *as, RAnalOp *op, ut64 addr, const ut8 *buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int parse_reg_name(RRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
|
||||
if (!reg) {
|
||||
return -1;
|
||||
}
|
||||
static const char *parse_reg_name(csh handle, cs_insn *insn, int reg_num) {
|
||||
switch (INSOP (reg_num).type) {
|
||||
case PPC_OP_REG:
|
||||
reg->name = (char *)cs_reg_name (handle, INSOP (reg_num).reg);
|
||||
break;
|
||||
return cs_reg_name (handle, INSOP (reg_num).reg);
|
||||
case PPC_OP_MEM:
|
||||
if (INSOP (reg_num).mem.base != PPC_REG_INVALID) {
|
||||
reg->name = (char *)cs_reg_name (handle, INSOP (reg_num).mem.base);
|
||||
return cs_reg_name (handle, INSOP (reg_num).mem.base);
|
||||
}
|
||||
break;
|
||||
default :
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RRegItem base_regs[4];
|
||||
|
||||
static void create_src_dst(RAnalOp *op) {
|
||||
r_vector_push (&op->srcs, NULL);
|
||||
r_vector_push (&op->srcs, NULL);
|
||||
r_vector_push (&op->srcs, NULL);
|
||||
r_vector_push (&op->dsts, NULL);
|
||||
ZERO_FILL (base_regs[0]);
|
||||
ZERO_FILL (base_regs[1]);
|
||||
ZERO_FILL (base_regs[2]);
|
||||
ZERO_FILL (base_regs[3]);
|
||||
}
|
||||
|
||||
static void set_src_dst(RAnalValue *val, csh *handle, cs_insn *insn, int x) {
|
||||
cs_ppc_op ppcop = INSOP (x);
|
||||
parse_reg_name (&base_regs[x], *handle, insn, x);
|
||||
val->reg = parse_reg_name (*handle, insn, x);
|
||||
switch (ppcop.type) {
|
||||
case PPC_OP_REG:
|
||||
break;
|
||||
@ -480,7 +470,6 @@ static void set_src_dst(RAnalValue *val, csh *handle, cs_insn *insn, int x) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
val->reg = &base_regs[x];
|
||||
}
|
||||
|
||||
static void op_fillval(RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
|
@ -54,23 +54,18 @@ static void opex(RStrBuf *buf, csh handle, cs_insn *insn) {
|
||||
pj_free (pj);
|
||||
}
|
||||
|
||||
static int parse_reg_name(RRegItem *reg, csh handle, cs_insn *insn, int reg_num) {
|
||||
if (!reg) {
|
||||
return -1;
|
||||
}
|
||||
static const char *parse_reg_name(csh handle, cs_insn *insn, int reg_num) {
|
||||
switch (INSOP (reg_num).type) {
|
||||
case SPARC_OP_REG:
|
||||
reg->name = (char *)cs_reg_name (handle, INSOP (reg_num).reg);
|
||||
break;
|
||||
return cs_reg_name (handle, INSOP (reg_num).reg);
|
||||
case SPARC_OP_MEM:
|
||||
if (INSOP (reg_num).mem.base != SPARC_REG_INVALID) {
|
||||
reg->name = (char *)cs_reg_name (handle, INSOP (reg_num).mem.base);
|
||||
break;
|
||||
return cs_reg_name (handle, INSOP (reg_num).mem.base);
|
||||
}
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_capstone_mode(RArchSession *as) {
|
||||
@ -105,8 +100,7 @@ static void op_fillval(PluginData *pd, RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
if (INSOP (0).type == SPARC_OP_MEM) {
|
||||
memset (reg, 0, sizeof (RRegItem));
|
||||
val = r_vector_push (&op->srcs, NULL);
|
||||
val->reg = reg;
|
||||
parse_reg_name (val->reg, handle, insn, 0);
|
||||
val->reg = parse_reg_name (handle, insn, 0);
|
||||
val->delta = INSOP(0).mem.disp;
|
||||
}
|
||||
break;
|
||||
@ -114,8 +108,7 @@ static void op_fillval(PluginData *pd, RAnalOp *op, csh handle, cs_insn *insn) {
|
||||
if (INSOP (1).type == SPARC_OP_MEM) {
|
||||
memset (reg, 0, sizeof (RRegItem));
|
||||
val = r_vector_push (&op->dsts, NULL);
|
||||
val->reg = reg;
|
||||
parse_reg_name (val->reg, handle, insn, 1);
|
||||
val->reg = parse_reg_name (handle, insn, 1);
|
||||
val->delta = INSOP(1).mem.disp;
|
||||
}
|
||||
break;
|
||||
|
@ -4930,13 +4930,11 @@ static const char *reg_name_for_access(RAnalOp* op, RAnalVarAccessType 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 (dst && dst->reg) {
|
||||
return dst->reg->name;
|
||||
}
|
||||
} else {
|
||||
if (src && src->reg) {
|
||||
return src->reg->name;
|
||||
if (dst) {
|
||||
return dst->reg;
|
||||
}
|
||||
} else if (src) {
|
||||
return src->reg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -5674,13 +5672,13 @@ R_API void r_core_anal_esil(RCore *core, const char *str /* len */, const char *
|
||||
ut64 dst = ESIL->cur;
|
||||
RAnalValue *opsrc0 = r_vector_at (&op.srcs, 0);
|
||||
RAnalValue *opsrc1 = r_vector_at (&op.srcs, 1);
|
||||
if (!opsrc0 || !opsrc0->reg || !opsrc0->reg->name) {
|
||||
if (!opsrc0 || !opsrc0->reg) {
|
||||
break;
|
||||
}
|
||||
if (!strcmp (opsrc0->reg->name, "sp")) {
|
||||
if (!strcmp (opsrc0->reg, "sp")) {
|
||||
break;
|
||||
}
|
||||
if (!strcmp (opsrc0->reg->name, "zero")) {
|
||||
if (!strcmp (opsrc0->reg, "zero")) {
|
||||
break;
|
||||
}
|
||||
if ((target && dst == ntarget) || !target) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2009-2022 - pancake, oddcoder, Anton Kochkov, Jody Frankowski */
|
||||
/* radare - LGPL - Copyright 2009-2023 - pancake, oddcoder, Anton Kochkov, Jody Frankowski */
|
||||
|
||||
#include <r_core.h>
|
||||
|
||||
@ -998,14 +998,14 @@ R_API void r_core_link_stroff(RCore *core, RAnalFunction *fcn) {
|
||||
ut64 dst_addr = UT64_MAX;
|
||||
RAnalValue *src = NULL;
|
||||
r_vector_foreach (&aop.srcs, src) {
|
||||
if (src && src->reg && src->reg->name) {
|
||||
src_addr = r_reg_getv (esil->anal->reg, src->reg->name) + index;
|
||||
if (src && src->reg) {
|
||||
src_addr = r_reg_getv (esil->anal->reg, src->reg) + index;
|
||||
src_imm = src->delta;
|
||||
}
|
||||
}
|
||||
RAnalValue *dst = r_vector_at (&aop.dsts, 0);
|
||||
if (dst && dst->reg && dst->reg->name) {
|
||||
dst_addr = r_reg_getv (esil->anal->reg, dst->reg->name) + index;
|
||||
if (dst && dst->reg) {
|
||||
dst_addr = r_reg_getv (esil->anal->reg, dst->reg) + index;
|
||||
dst_imm = dst->delta;
|
||||
}
|
||||
RAnalVar *var = r_anal_get_used_function_var (core->anal, aop.addr);
|
||||
|
@ -83,14 +83,14 @@ R_API bool r_debug_trace_ins_before(RDebug *dbg) {
|
||||
ut64 addr = 0;
|
||||
addr += val->delta;
|
||||
if (val->seg) {
|
||||
addr += r_reg_get_value (dbg->reg, val->seg);
|
||||
addr += r_reg_getv (dbg->reg, val->seg);
|
||||
}
|
||||
if (val->reg) {
|
||||
addr += r_reg_get_value (dbg->reg, val->reg);
|
||||
addr += r_reg_getv (dbg->reg, val->reg);
|
||||
}
|
||||
if (val->regdelta) {
|
||||
int mul = val->mul ? val->mul : 1;
|
||||
addr += mul * r_reg_get_value (dbg->reg, val->regdelta);
|
||||
addr += mul * r_reg_getv (dbg->reg, val->regdelta);
|
||||
}
|
||||
// resolve address into base for ins_after
|
||||
val->base = addr;
|
||||
@ -122,10 +122,14 @@ R_API bool r_debug_trace_ins_after(RDebug *dbg) {
|
||||
R_LOG_ERROR ("invalid register, unable to trace register state");
|
||||
continue;
|
||||
}
|
||||
ut64 data = r_reg_get_value (dbg->reg, val->reg);
|
||||
|
||||
// add reg write
|
||||
r_debug_session_add_reg_change (dbg->session, val->reg->arena, val->reg->offset, data);
|
||||
RRegItem *ri = r_reg_get (dbg->reg, val->reg, -1);
|
||||
if (ri) {
|
||||
// add reg write
|
||||
ut64 data = r_reg_get_value (dbg->reg, ri);
|
||||
r_debug_session_add_reg_change (dbg->session, ri->arena, ri->offset, data);
|
||||
} else {
|
||||
R_LOG_WARN ("Missing register %s", val->reg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case R_ANAL_VAL_MEM:
|
||||
|
@ -17,9 +17,9 @@ typedef enum {
|
||||
|
||||
#if R2_590
|
||||
#define USE_REG_NAMES 1
|
||||
#define R_ARCH_INFO_MIN_OP_SIZE 0
|
||||
#define R_ARCH_INFO_MAX_OP_SIZE 1
|
||||
#define R_ARCH_INFO_INV_OP_SIZE 2
|
||||
#define R_ARCH_INFO_MINOP_SIZE 0
|
||||
#define R_ARCH_INFO_MAXOP_SIZE 1
|
||||
#define R_ARCH_INFO_INVOP_SIZE 2
|
||||
#define R_ARCH_INFO_ALIGN 4
|
||||
#define R_ARCH_INFO_DATA_ALIGN 8
|
||||
#define R_ARCH_INFO_DATA2_ALIGN 16
|
||||
@ -34,7 +34,6 @@ typedef enum {
|
||||
#define R_ANAL_ARCHINFO_DATA_ALIGN 8
|
||||
#endif
|
||||
|
||||
|
||||
// base + reg + regdelta * mul + delta
|
||||
typedef struct r_arch_value_t {
|
||||
RArchValueType type;
|
||||
@ -45,16 +44,9 @@ typedef struct r_arch_value_t {
|
||||
st64 delta; // numeric delta
|
||||
st64 imm; // immediate value
|
||||
int mul; // multiplier (reg*4+base)
|
||||
#if USE_REG_NAMES
|
||||
const char * const seg;
|
||||
const char * const reg;
|
||||
const char * const regdelta;
|
||||
#else
|
||||
// XXX can be invalidated if regprofile changes causing an UAF
|
||||
RRegItem *seg; // segment selector register
|
||||
RRegItem *reg; // register item reference
|
||||
RRegItem *regdelta; // register index used
|
||||
#endif
|
||||
const char *seg;
|
||||
const char *reg;
|
||||
const char *regdelta;
|
||||
} RArchValue;
|
||||
#include <r_anal/op.h>
|
||||
|
||||
@ -101,9 +93,7 @@ typedef struct r_arch_config_t {
|
||||
int invhex;
|
||||
int bitshift;
|
||||
char *abi;
|
||||
#if R2_590
|
||||
ut64 gp;
|
||||
#endif
|
||||
R_REF_TYPE;
|
||||
} RArchConfig;
|
||||
|
||||
@ -146,13 +136,11 @@ typedef struct r_arch_t {
|
||||
} RArch;
|
||||
|
||||
typedef struct r_arch_session_t {
|
||||
#if R2_590
|
||||
char *name; // used by .use to chk if it was set already
|
||||
// TODO: name it "peer" instead of encoder. so the encoder can back reference the decoder
|
||||
struct r_arch_session_t *encoder; // used for encoding when plugin->encode is not set
|
||||
#endif
|
||||
struct r_arch_t *arch;
|
||||
struct r_arch_plugin_t *plugin; // used for decoding
|
||||
struct r_arch_session_t *encoder; // used for encoding when plugin->encode is not set
|
||||
RArchConfig *config; // TODO remove arch->config!
|
||||
void *data;
|
||||
void *user;
|
||||
@ -232,11 +220,6 @@ R_API bool r_arch_add(RArch *arch, RArchPlugin *ap);
|
||||
R_API bool r_arch_del(RArch *arch, const char *name);
|
||||
R_API void r_arch_free(RArch *arch);
|
||||
|
||||
// R2_590 - deprecate
|
||||
R_API bool r_arch_set_bits(RArch *arch, ut32 bits);
|
||||
R_API bool r_arch_set_endian(RArch *arch, ut32 endian);
|
||||
R_API bool r_arch_set_arch(RArch *arch, char *archname);
|
||||
|
||||
// aconfig.c
|
||||
R_API void r_arch_config_use(RArchConfig *config, R_NULLABLE const char *arch);
|
||||
R_API void r_arch_config_set_cpu(RArchConfig *config, R_NULLABLE const char *cpu);
|
||||
@ -250,9 +233,7 @@ R_API void r_arch_config_free(RArchConfig *);
|
||||
#define RAnalValue RArchValue
|
||||
R_API RArchValue *r_arch_value_new(void);
|
||||
|
||||
#if R2_590
|
||||
R_API RArchValue *r_arch_value_new_reg(const char * const regname);
|
||||
#endif
|
||||
#if 0
|
||||
// switchop
|
||||
R_API RArchSwitchOp *r_arch_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val);
|
||||
@ -271,6 +252,13 @@ R_API void r_arch_op_fini(RAnalOp *op);
|
||||
R_API void r_arch_op_free(void *_op);
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
// R2_590 Deprecate!
|
||||
R_API bool r_arch_set_endian(RArch *arch, ut32 endian);
|
||||
R_API bool r_arch_set_bits(RArch *arch, ut32 bits);
|
||||
R_API bool r_arch_set_arch(RArch *arch, char *archname);
|
||||
#endif
|
||||
|
||||
R_API int r_arch_optype_from_string(const char *type);
|
||||
R_API const char *r_arch_optype_tostring(int t);
|
||||
R_API const char *r_arch_stackop_tostring(int s);
|
||||
|
Loading…
Reference in New Issue
Block a user