From 340ccc481b4b0d72294cc083a8b2d23457f33f5c Mon Sep 17 00:00:00 2001 From: Nibble Date: Fri, 18 Feb 2011 13:08:09 +0100 Subject: [PATCH] * Add more vm features to r_anal * Fix syscall recognition --- libr/anal/anal.c | 11 ++- libr/anal/cc.c | 11 ++- libr/anal/p/anal_arm.c | 31 +++++++ libr/anal/p/anal_avr.c | 3 +- libr/anal/p/anal_csr.c | 3 +- libr/anal/p/anal_ppc.c | 61 ++++++++++++- libr/anal/p/anal_x86.c | 157 ++++++++++++++++++++++++++++++++-- libr/anal/p/anal_x86_simple.c | 3 +- libr/include/r_anal.h | 7 +- 9 files changed, 273 insertions(+), 14 deletions(-) diff --git a/libr/anal/anal.c b/libr/anal/anal.c index 4f11ad7600..0281935649 100644 --- a/libr/anal/anal.c +++ b/libr/anal/anal.c @@ -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; diff --git a/libr/anal/cc.c b/libr/anal/cc.c index 39d1ec2825..436ea3293a 100644 --- a/libr/anal/cc.c +++ b/libr/anal/cc.c @@ -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 ++; diff --git a/libr/anal/p/anal_arm.c b/libr/anal/p/anal_arm.c index 8160ae39ff..aa07e424cc 100644 --- a/libr/anal/p/anal_arm.c +++ b/libr/anal/p/anal_arm.c @@ -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", diff --git a/libr/anal/p/anal_avr.c b/libr/anal/p/anal_avr.c index 0e92a304be..bea716185f 100644 --- a/libr/anal/p/anal_avr.c +++ b/libr/anal/p/anal_avr.c @@ -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 diff --git a/libr/anal/p/anal_csr.c b/libr/anal/p/anal_csr.c index 26cf89ce7d..e2a6b03e94 100644 --- a/libr/anal/p/anal_csr.c +++ b/libr/anal/p/anal_csr.c @@ -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 diff --git a/libr/anal/p/anal_ppc.c b/libr/anal/p/anal_ppc.c index 854be1073a..3426be3f37 100644 --- a/libr/anal/p/anal_ppc.c +++ b/libr/anal/p/anal_ppc.c @@ -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 diff --git a/libr/anal/p/anal_x86.c b/libr/anal/p/anal_x86.c index e000214e28..8e3a00480d 100644 --- a/libr/anal/p/anal_x86.c +++ b/libr/anal/p/anal_x86.c @@ -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 diff --git a/libr/anal/p/anal_x86_simple.c b/libr/anal/p/anal_x86_simple.c index 702842b36d..260eca1b3d 100644 --- a/libr/anal/p/anal_x86_simple.c +++ b/libr/anal/p/anal_x86_simple.c @@ -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 diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 8871d32b70..ec4179e199 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -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);