* Add more vm features to r_anal

* Fix syscall recognition
This commit is contained in:
Nibble 2011-02-18 13:08:09 +01:00
parent 5c1d473b69
commit 340ccc481b
9 changed files with 273 additions and 14 deletions

View File

@ -27,7 +27,7 @@ R_API RAnal *r_anal_new() {
memset (anal, 0, sizeof (RAnal));
anal->syscall = r_syscall_new ();
r_io_bind_init (anal->iob);
anal->reg = NULL;
anal->reg = r_reg_new ();
anal->lineswidth = 0;
anal->fcns = r_anal_fcn_list_new ();
anal->refs = r_anal_ref_list_new ();
@ -85,12 +85,20 @@ R_API int r_anal_use(RAnal *anal, const char *name) {
RAnalPlugin *h = list_entry(pos, RAnalPlugin, list);
if (!strcmp (h->name, name)) {
anal->cur = h;
r_anal_set_reg_profile (anal);
return R_TRUE;
}
}
return R_FALSE;
}
R_API int r_anal_set_reg_profile(RAnal *anal) {
if (anal)
if (anal->cur && anal->cur->set_reg_profile)
return anal->cur->set_reg_profile (anal);
return R_FALSE;
}
R_API int r_anal_set_bits(RAnal *anal, int bits) {
switch (bits) {
case 8:
@ -98,6 +106,7 @@ R_API int r_anal_set_bits(RAnal *anal, int bits) {
case 32:
case 64:
anal->bits = bits;
r_anal_set_reg_profile (anal);
return R_TRUE;
}
return R_FALSE;

View File

@ -106,7 +106,16 @@ R_API boolt r_anal_cc_update (RAnal *anal, RAnalCC *cc, RAnalOp *op) {
cc->off = op->jump;
cc->jump = op->value; // syscall number
return R_FALSE;
//case R_ANAL_OP_TYPE_MOV:
case R_ANAL_OP_TYPE_MOV:
{
RRegItem *it;
if (op->dst && op->dst->reg) {
it = r_reg_get (anal->reg, op->dst->reg->name, R_REG_TYPE_GPR);
if (it && op->src[0])
r_reg_set_value (anal-> reg, it, op->src[0]->imm);
}
return R_TRUE;
}
case R_ANAL_OP_TYPE_PUSH:
case R_ANAL_OP_TYPE_UPUSH: // add argument
cc->nargs ++;

View File

@ -237,6 +237,37 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
}
return aop->length;
}
static int set_reg_profile(RAnal *anal) {
/* XXX Dupped Profiles */
return r_reg_set_profile_string (anal->reg,
"=pc r15\n"
"=sp r14\n" // XXX
"=a0 r0\n"
"=a1 r1\n"
"=a2 r2\n"
"=a3 r3\n"
"gpr lr .32 56 0\n" // r14
"gpr pc .32 60 0\n" // r15
"gpr r0 .32 0 0\n"
"gpr r1 .32 4 0\n"
"gpr r2 .32 8 0\n"
"gpr r3 .32 12 0\n"
"gpr r4 .32 16 0\n"
"gpr r5 .32 20 0\n"
"gpr r6 .32 24 0\n"
"gpr r7 .32 28 0\n"
"gpr r8 .32 32 0\n"
"gpr r9 .32 36 0\n"
"gpr r10 .32 40 0\n"
"gpr r11 .32 44 0\n"
"gpr r12 .32 48 0\n"
"gpr r13 .32 52 0\n"
"gpr r14 .32 56 0\n"
"gpr r15 .32 60 0\n"
"gpr r16 .32 64 0\n"
"gpr r17 .32 68 0\n");
}
struct r_anal_plugin_t r_anal_plugin_arm = {
.name = "arm",

View File

@ -45,7 +45,8 @@ struct r_anal_plugin_t r_anal_plugin_avr = {
.desc = "AVR code analysis plugin",
.init = NULL,
.fini = NULL,
.aop = &aop
.aop = &aop,
.set_reg_profile = NULL
};
#ifndef CORELIB

View File

@ -227,7 +227,8 @@ struct r_anal_plugin_t r_anal_plugin_csr = {
.desc = "CSR code analysis plugin",
.init = NULL,
.fini = NULL,
.aop = &aop
.aop = &aop,
.set_reg_profile = NULL
};
#ifndef CORELIB

View File

@ -74,12 +74,71 @@ int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *bytes, int len) {
return aop->length;
}
static int set_reg_profile(RAnal *anal) {
/* XXX Dupped Profiles */
return r_reg_set_profile_string (anal->reg,
"=pc srr0\n"
"=sr srr1\n" // status register
"=a0 r0\n"
"=a1 r1\n"
"=a2 r2\n"
"=a3 r3\n"
#if 0
"=a4 r4\n"
"=a5 r5\n"
"=a6 r6\n"
"=a7 r7\n"
#endif
"gpr srr0 .32 0 0\n"
"gpr srr1 .32 4 0\n"
"gpr r0 .32 8 0\n"
"gpr r1 .32 12 0\n"
"gpr r2 .32 16 0\n"
"gpr r3 .32 20 0\n"
"gpr r4 .32 24 0\n"
"gpr r5 .32 28 0\n"
"gpr r6 .32 32 0\n"
"gpr r7 .32 36 0\n"
"gpr r8 .32 40 0\n"
"gpr r9 .32 44 0\n"
"gpr r10 .32 48 0\n"
"gpr r11 .32 52 0\n"
"gpr r12 .32 56 0\n"
"gpr r13 .32 60 0\n"
"gpr r14 .32 64 0\n"
"gpr r15 .32 68 0\n"
"gpr r16 .32 72 0\n"
"gpr r17 .32 76 0\n"
"gpr r18 .32 80 0\n"
"gpr r19 .32 84 0\n"
"gpr r20 .32 88 0\n"
"gpr r21 .32 92 0\n"
"gpr r22 .32 96 0\n"
"gpr r23 .32 100 0\n"
"gpr r24 .32 104 0\n"
"gpr r25 .32 108 0\n"
"gpr r26 .32 112 0\n"
"gpr r27 .32 116 0\n"
"gpr r28 .32 120 0\n"
"gpr r29 .32 124 0\n"
"gpr r30 .32 128 0\n"
"gpr r31 .32 132 0\n"
"gpr cr .32 136 0\n"
"gpr xer .32 140 0\n"
"gpr lr .32 144 0\n"
"gpr ctr .32 148 0\n"
"gpr mq .32 152 0\n"
"gpr vrsave .32 156 0\n");
}
struct r_anal_plugin_t r_anal_plugin_ppc = {
.name = "ppc",
.desc = "PowerPC analysis plugin",
.init = NULL,
.fini = NULL,
.aop = &aop
.aop = &aop,
.set_reg_profile = &set_reg_profile
};
#ifndef CORELIB

View File

@ -595,16 +595,13 @@ static void anal_sub(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
}
static void anal_int(RAnal *anal, RAnalOp *aop, x86im_instr_object io) {
st64 imm;
imm = r_hex_bin_truncate (io.imm, io.imm_size);
aop->type = R_ANAL_OP_TYPE_SWI;
switch (io.id) {
case X86IM_IO_ID_INTN:
aop->ref = imm;
aop->value = io.imm; /* io.imm doesn't need to be trucated here */
break;
case X86IM_IO_ID_INT3:
aop->ref = 3;
aop->value = 3;
break;
case X86IM_IO_ID_INTO:
break;
@ -711,12 +708,160 @@ static int aop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len) {
return aop->length;
}
static int set_reg_profile(RAnal *anal) {
/* XXX Dupped Profiles */
if (anal->bits == 32)
#if __WINDOWS__
return r_reg_set_profile_string (anal->reg,
"=pc eip\n"
"=sp esp\n"
"=bp ebp\n"
"=a0 eax\n"
"=a1 ebx\n"
"=a2 ecx\n"
"=a3 edi\n"
"drx dr0 .32 4 0\n"
"drx dr1 .32 8 0\n"
"drx dr2 .32 12 0\n"
"drx dr3 .32 16 0\n"
"drx dr6 .32 20 0\n"
"drx dr7 .32 24 0\n"
/* floating save area 4+4+4+4+4+4+4+80+4 = 112 */
"seg gs .32 132 0\n"
"seg fs .32 136 0\n"
"seg es .32 140 0\n"
"seg ds .32 144 0\n"
"gpr edi .32 156 0\n"
"gpr esi .32 160 0\n"
"gpr ebx .32 164 0\n"
"gpr edx .32 168 0\n"
"gpr ecx .32 172 0\n"
"gpr eax .32 176 0\n"
"gpr ebp .32 180 0\n"
"gpr esp .32 196 0\n"
"gpr eip .32 184 0\n"
"seg cs .32 184 0\n"
"seg ds .32 152 0\n"
"seg gs .32 140 0\n"
"seg fs .32 144 0\n"
"gpr eflags .32 192 0 c1p.a.zstido.n.rv\n" // XXX must be flg
"seg ss .32 200 0\n"
/* +512 bytes for maximum supoprted extension extended registers */
);
#else
return r_reg_set_profile_string (anal->reg,
"=pc eip\n"
"=sp esp\n"
"=bp ebp\n"
"=a0 eax\n"
"=a1 ebx\n"
"=a2 ecx\n"
"=a3 edi\n"
"gpr eip .32 48 0\n"
"gpr ip .16 48 0\n"
"gpr oeax .32 44 0\n"
"gpr eax .32 24 0\n"
"gpr ax .16 24 0\n"
"gpr ah .8 24 0\n"
"gpr al .8 25 0\n"
"gpr ebx .32 0 0\n"
"gpr bx .16 0 0\n"
"gpr bh .8 0 0\n"
"gpr bl .8 1 0\n"
"gpr ecx .32 4 0\n"
"gpr cx .16 4 0\n"
"gpr ch .8 4 0\n"
"gpr cl .8 5 0\n"
"gpr edx .32 8 0\n"
"gpr dx .16 8 0\n"
"gpr dh .8 8 0\n"
"gpr dl .8 9 0\n"
"gpr esp .32 60 0\n"
"gpr sp .16 60 0\n"
"gpr ebp .32 20 0\n"
"gpr bp .16 20 0\n"
"gpr esi .32 12 0\n"
"gpr si .16 12 0\n"
"gpr edi .32 16 0\n"
"gpr di .16 16 0\n"
"seg xfs .32 36 0\n"
"seg xgs .32 40 0\n"
"seg xcs .32 52 0\n"
"seg cs .16 52 0\n"
"seg xss .32 52 0\n"
"gpr eflags .32 56 0 c1p.a.zstido.n.rv\n"
"gpr flags .16 56 0\n"
"flg carry .1 .448 0\n"
"flg flag_p .1 .449 0\n"
"flg flag_a .1 .450 0\n"
"flg zero .1 .451 0\n"
"flg sign .1 .452 0\n"
"flg flag_t .1 .453 0\n"
"flg flag_i .1 .454 0\n"
"flg flag_d .1 .455 0\n"
"flg flag_o .1 .456 0\n"
"flg flag_r .1 .457 0\n"
"drx dr0 .32 0 0\n"
"drx dr1 .32 4 0\n"
"drx dr2 .32 8 0\n"
"drx dr3 .32 12 0\n"
//"drx dr4 .32 16 0\n"
//"drx dr5 .32 20 0\n"
"drx dr6 .32 24 0\n"
"drx dr7 .32 28 0\n");
#endif
else return r_reg_set_profile_string (anal->reg,
"=pc rip\n"
"=sp rsp\n"
"=bp rbp\n"
"=a0 rax\n"
"=a1 rbx\n"
"=a2 rcx\n"
"=a3 rdx\n"
"# no profile defined for x86-64\n"
"gpr r15 .64 0 0\n"
"gpr r14 .64 8 0\n"
"gpr r13 .64 16 0\n"
"gpr r12 .64 24 0\n"
"gpr rbp .64 32 0\n"
"gpr rbx .64 40 0\n"
"gpr r11 .64 48 0\n"
"gpr r10 .64 56 0\n"
"gpr r9 .64 64 0\n"
"gpr r8 .64 72 0\n"
"gpr rax .64 80 0\n"
"gpr rcx .64 88 0\n"
"gpr rdx .64 96 0\n"
"gpr rsi .64 104 0\n"
"gpr rdi .64 112 0\n"
"gpr oeax .64 120 0\n"
"gpr rip .64 128 0\n"
"seg cs .64 136 0\n"
//"flg eflags .64 144 0\n"
"gpr eflags .32 144 0 c1p.a.zstido.n.rv\n"
"gpr rsp .64 152 0\n"
"seg ss .64 160 0\n"
"seg fs_base .64 168 0\n"
"seg gs_base .64 176 0\n"
"seg ds .64 184 0\n"
"seg es .64 192 0\n"
"seg fs .64 200 0\n"
"seg gs .64 208 0\n"
"drx dr0 .32 0 0\n"
"drx dr1 .32 4 0\n"
"drx dr2 .32 8 0\n"
"drx dr3 .32 12 0\n"
"drx dr6 .32 24 0\n"
"drx dr7 .32 28 0\n");
}
struct r_anal_plugin_t r_anal_plugin_x86 = {
.name = "x86",
.desc = "X86 analysis plugin (x86im backend)",
.init = NULL,
.fini = NULL,
.aop = &aop
.aop = &aop,
.set_reg_profile = &set_reg_profile
};
#ifndef CORELIB

View File

@ -517,7 +517,8 @@ struct r_anal_plugin_t r_anal_plugin_x86_simple = {
.desc = "X86 analysis plugin",
.init = NULL,
.fini = NULL,
.aop = &myaop
.aop = &myaop,
.set_reg_profile = NULL
};
#ifndef CORELIB

View File

@ -305,14 +305,16 @@ typedef struct r_anal_refline_t {
struct list_head list;
} RAnalRefline;
typedef int (*RAnalCallback)(RAnal *a, RAnalOp *aop, ut64 addr, const ut8 *data, int len);
typedef int (*RAnalAopCallback)(RAnal *a, RAnalOp *aop, ut64 addr, const ut8 *data, int len);
typedef int (*RAnalRegProfCallback)(RAnal *a);
typedef struct r_anal_plugin_t {
char *name;
char *desc;
int (*init)(void *user);
int (*fini)(void *user);
RAnalCallback aop;
RAnalAopCallback aop;
RAnalRegProfCallback set_reg_profile;
struct list_head list;
} RAnalPlugin;
@ -324,6 +326,7 @@ R_API void r_anal_set_user_ptr(RAnal *anal, void *user);
R_API int r_anal_add(RAnal *anal, struct r_anal_plugin_t *foo);
R_API int r_anal_list(RAnal *anal);
R_API int r_anal_use(RAnal *anal, const char *name);
R_API int r_anal_set_reg_profile(RAnal *anal);
R_API int r_anal_set_bits(RAnal *anal, int bits);
R_API int r_anal_set_big_endian(RAnal *anal, int boolean);
R_API char *r_anal_strmask (RAnal *anal, const char *data);