* Fix r2 build

- Add CFLAGS+=-DCORELIB in libr/cmd/Makefile
  - Add target all in r2rc/Makefile
* r_core
  - Add dummy command ac (stands for analyze code)
* r_anal
  - Reorganize code
  - Add function r_anal_bbs (not working yet)
This commit is contained in:
Nibble 2010-02-26 13:08:42 +01:00
parent de65dc6205
commit 54e804eec9
9 changed files with 262 additions and 182 deletions

View File

@ -1,5 +1,5 @@
NAME=r_anal
DEPS=r_util r_lib
OBJ=anal.o ctx.o
OBJ=anal.o ctx.o reflines.o
include ../rules.mk

View File

@ -4,22 +4,45 @@
#include <r_anal.h>
#include <r_util.h>
#include <r_list.h>
R_API RAnalysis *r_anal_new() {
return r_anal_init (MALLOC_STRUCT (struct r_anal_t));
}
R_API RList *r_anal_bb_list_new() {
RList *list = r_list_new ();
list->free = &r_anal_bb_list_free;
return list;
}
R_API RList *r_anal_aop_list_new() {
RList *list = r_list_new ();
list->free = &r_anal_aop_list_free;
return list;
}
R_API RAnalysis *r_anal_free(struct r_anal_t *a) {
/* TODO: Free a->anals here */
/* TODO: Free a->bbs here */
free (a);
return NULL;
}
R_API void r_anal_bb_list_free(void *bbs) {
/* TODO */
}
R_API void r_anal_aop_list_free(void *aops) {
/* TODO */
}
R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal) {
if (anal) {
anal->user = NULL;
anal->ctx = NULL;
anal->cur = NULL;
anal->bbs = r_anal_bb_list_new();
r_anal_set_bits (anal, 32);
r_anal_set_big_endian (anal, R_FALSE);
INIT_LIST_HEAD (&anal->anals);
@ -83,130 +106,37 @@ R_API int r_anal_aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr,
return R_FALSE;
}
R_API struct r_anal_fcn_t *r_anal_funcions_get(struct r_anal_t *anal, ut8 *buf, ut64 len) {
return NULL;
}
R_API int r_anal_bbs(struct r_anal_t *anal, ut64 addr, ut8 *buf, ut64 len) {
/* XXX No working*/
struct r_anal_bb_t *bb;
struct r_anal_aop_t *aop;
ut64 oplen;
R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout)
{
struct r_anal_refline_t *list = MALLOC_STRUCT (struct r_anal_refline_t);
struct r_anal_refline_t *list2;
struct r_anal_aop_t aop;
ut8 *ptr = buf;
ut8 *end = buf + len;
ut64 opc = addr;
int sz = 0, index = 0;
INIT_LIST_HEAD(&(list->list));
/* analyze code block */
while (ptr<end) {
if (nlines != -1 && --nlines == 0)
break;
#if 0
if (config.interrupted)
break;
int dt = data_type(config.seek+bsz);
if (dt != DATA_FUN && dt != DATA_CODE) {
ut64 sz = data_size(config.seek+bsz);
if (sz > 0) {
ptr= ptr +sz;
bsz=bsz+sz;
continue;
}
}
#endif
addr += sz;
sz = r_anal_aop (anal, &aop, addr, ptr, (int)(end-ptr));
if (sz > 0) {
/* store data */
switch(aop.type) {
case R_ANAL_OP_TYPE_CALL:
case R_ANAL_OP_TYPE_CJMP:
case R_ANAL_OP_TYPE_JMP:
if (!linesout && (aop.jump > opc+len || aop.jump < opc))
goto __next;
if (aop.jump == 0)
goto __next;
list2 = MALLOC_STRUCT(struct r_anal_refline_t);
list2->from = addr;
list2->to = aop.jump;
list2->index = index++;
list_add_tail(&(list2->list), &(list->list));
break;
}
} else sz = 1;
__next:
ptr = ptr + sz;
}
return list;
}
/* umf..this should probably be outside this file */
R_API int r_anal_reflines_str(struct r_anal_t *anal, struct r_anal_refline_t *list,
ut64 addr, char *str, int opts)
{
struct r_anal_refline_t *ref;
struct list_head *pos;
int dir = 0;
char ch = ' ';
int linestyle = opts & R_ANAL_REFLINE_STYLE;
int wide = opts & R_ANAL_REFLINE_WIDE;
if (!list)
if (!(bb = MALLOC_STRUCT(struct r_anal_bb_t))) {
eprintf ("Error: malloc (bb)\n");
return R_FALSE;
strcpy (str, " ");
for (pos = linestyle?(&(list->list))->next:(&(list->list))->prev;
pos != (&(list->list)); pos = linestyle?pos->next:pos->prev) {
ref = list_entry(pos, struct r_anal_refline_t, list);
if (addr == ref->to) dir = 1;
// TODO: use else here
if (addr == ref->from) dir = 2;
// TODO: if dir==1
if (addr == ref->to) {
if (ref->from > ref->to)
strcat(str, ".");
else strcat(str, "`");
ch = '-';
} else if (addr == ref->from) {
if (ref->from > ref->to)
strcat(str, "`");
else strcat(str, ".");
ch = '=';
} else if (ref->from < ref->to) { /* down */
if (addr > ref->from && addr < ref->to) {
if (ch=='-'||ch=='=')
r_str_concatch(str, ch);
else strcat(str, "|");
} else r_str_concatch(str, ch);
} else { /* up */
if (addr < ref->from && addr > ref->to) {
if (ch=='-'||ch=='=')
r_str_concatch(str, ch);
else strcat(str, "|");
} else r_str_concatch(str, ch);
}
if (wide) {
if (ch == '=' || ch == '-')
r_str_concatch(str, ch);
else strcat(str, " ");
}
}
switch (dir) {
case 1: strcat(str, "-> "); break;
case 2: strcat(str, "=< "); break;
default: strcat(str, " "); break;
r_list_append (anal->bbs, bb);
bb->addr = addr;
for (;;) {
if (!(aop = MALLOC_STRUCT(struct r_anal_aop_t))) {
eprintf ("Error: malloc (aop)\n");
return R_FALSE;
}
if (!(oplen = r_anal_aop (anal, aop, addr, buf, len)))
break;
r_list_append (bb->aops, aop);
switch (aop->type) {
case R_ANAL_OP_TYPE_CJMP:
bb->fail = aop->fail;
r_anal_bbs (anal, bb->fail, buf, len);
case R_ANAL_OP_TYPE_JMP:
bb->jump = aop->jump;
r_anal_bbs (anal, bb->jump, buf, len);
bb->size = addr + oplen - bb->addr;
break;
}
addr += oplen;
}
return R_TRUE;
}

View File

@ -27,7 +27,7 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
aop->length = Disasm(&disasm_obj);
IFDBG {
printf( "[Instruction]\n"
eprintf( "[Instruction]\n"
" Opcode: %lx\n"
" Mnemonic: %s\n"
" AddrValue: 0x%llx\n"
@ -225,7 +225,7 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
default:
strcat(category, "UNKNOWN_INSTRUCTION ");
}
printf(" Category: %s\n", category);
eprintf(" Category: %s\n", category);
switch (disasm_obj.Instruction.BranchType) {
case JO:
@ -250,25 +250,25 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
aop->type = R_ANAL_OP_TYPE_CJMP;
aop->jump = disasm_obj.Instruction.AddrValue;
aop->fail = disasm_obj.Instruction.AddrValue + aop->length;
printf(" BranchType: JO\n");
eprintf(" BranchType: JO\n");
break;
case JmpType:
aop->type = R_ANAL_OP_TYPE_JMP;
aop->jump = disasm_obj.Instruction.AddrValue;
printf(" BranchType: JmpType\n");
eprintf(" BranchType: JmpType\n");
break;
case CallType:
aop->type = R_ANAL_OP_TYPE_CALL;
aop->jump = disasm_obj.Instruction.AddrValue;
aop->fail = disasm_obj.Instruction.AddrValue + aop->length;
printf(" BranchType: CallType\n");
eprintf(" BranchType: CallType\n");
break;
case RetType:
aop->type = R_ANAL_OP_TYPE_RET;
printf(" BranchType: RetType\n");
eprintf(" BranchType: RetType\n");
break;
default:
printf(" BranchType: Unknown (0x%lx)\n", disasm_obj.Instruction.BranchType);
eprintf(" BranchType: Unknown (0x%lx)\n", disasm_obj.Instruction.BranchType);
}
@ -276,7 +276,7 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
if (argptr[i].ArgMnemonic[0] == '\0')
continue;
printf( "[ARG%i]\n"
eprintf( "[ARG%i]\n"
" Mnemonic: %s\n"
" ArgSize: 0x%lx\n"
" BaseRegister: 0x%lx\n"
@ -294,12 +294,12 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
argptr[i].SegmentReg
);
printf(" AccesMode: ");
eprintf(" AccesMode: ");
if (argptr[i].AccessMode == 0x1)
printf("READ\n");
eprintf("READ\n");
else if (argptr[i].AccessMode == 0x2)
printf("WRITE\n");
else printf("UNKNOWN\n");
eprintf("WRITE\n");
else eprintf("UNKNOWN\n");
argtype[0] = '\0';
if (argptr[i].ArgType & NO_ARGUMENT)
@ -370,18 +370,18 @@ static int aop(struct r_anal_t *anal, struct r_anal_aop_t *aop, ut64 addr, void
strcat(argtype, "REG14 ");
if (argptr[i].ArgType & REG15)
strcat(argtype, "REG15 ");
printf(" ArgType: %s\n", argtype);
eprintf(" ArgType: %s\n", argtype);
}
printf("\n");
eprintf("\n");
}
printf("InternalOP:\n");
printf("Type: %d\n", aop->type);
printf("EOB: %d\n", aop->eob);
printf("Family: %d\n", aop->family);
printf("Stackop: %d\n", aop->stackop);
printf("True: 0x%08llx\n", aop->jump);
printf("Fail: 0x%08llx\n", aop->fail);
eprintf("InternalOP:\n");
eprintf("Type: %d\n", aop->type);
eprintf("EOB: %d\n", aop->eob);
eprintf("Family: %d\n", aop->family);
eprintf("Stackop: %d\n", aop->stackop);
eprintf("True: 0x%08llx\n", aop->jump);
eprintf("Fail: 0x%08llx\n", aop->fail);
return aop->length;
}

129
libr/anal/reflines.c Normal file
View File

@ -0,0 +1,129 @@
/* radare - LGPL - Copyright 2009-2010 */
/* nibble<.ds@gmail.com> */
/* pancake<nopcode.org> */
#include <r_anal.h>
#include <r_util.h>
R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout)
{
struct r_anal_refline_t *list = MALLOC_STRUCT (struct r_anal_refline_t);
struct r_anal_refline_t *list2;
struct r_anal_aop_t aop;
ut8 *ptr = buf;
ut8 *end = buf + len;
ut64 opc = addr;
int sz = 0, index = 0;
INIT_LIST_HEAD(&(list->list));
/* analyze code block */
while (ptr<end) {
if (nlines != -1 && --nlines == 0)
break;
#if 0
if (config.interrupted)
break;
int dt = data_type(config.seek+bsz);
if (dt != DATA_FUN && dt != DATA_CODE) {
ut64 sz = data_size(config.seek+bsz);
if (sz > 0) {
ptr= ptr +sz;
bsz=bsz+sz;
continue;
}
}
#endif
addr += sz;
sz = r_anal_aop (anal, &aop, addr, ptr, (int)(end-ptr));
if (sz > 0) {
/* store data */
switch(aop.type) {
case R_ANAL_OP_TYPE_CALL:
case R_ANAL_OP_TYPE_CJMP:
case R_ANAL_OP_TYPE_JMP:
if (!linesout && (aop.jump > opc+len || aop.jump < opc))
goto __next;
if (aop.jump == 0)
goto __next;
list2 = MALLOC_STRUCT(struct r_anal_refline_t);
list2->from = addr;
list2->to = aop.jump;
list2->index = index++;
list_add_tail(&(list2->list), &(list->list));
break;
}
} else sz = 1;
__next:
ptr = ptr + sz;
}
return list;
}
/* umf..this should probably be outside this file */
R_API int r_anal_reflines_str(struct r_anal_t *anal, struct r_anal_refline_t *list,
ut64 addr, char *str, int opts)
{
struct r_anal_refline_t *ref;
struct list_head *pos;
int dir = 0;
char ch = ' ';
int linestyle = opts & R_ANAL_REFLINE_STYLE;
int wide = opts & R_ANAL_REFLINE_WIDE;
if (!list)
return R_FALSE;
strcpy (str, " ");
for (pos = linestyle?(&(list->list))->next:(&(list->list))->prev;
pos != (&(list->list)); pos = linestyle?pos->next:pos->prev) {
ref = list_entry(pos, struct r_anal_refline_t, list);
if (addr == ref->to) dir = 1;
// TODO: use else here
if (addr == ref->from) dir = 2;
// TODO: if dir==1
if (addr == ref->to) {
if (ref->from > ref->to)
strcat(str, ".");
else strcat(str, "`");
ch = '-';
} else if (addr == ref->from) {
if (ref->from > ref->to)
strcat(str, "`");
else strcat(str, ".");
ch = '=';
} else if (ref->from < ref->to) { /* down */
if (addr > ref->from && addr < ref->to) {
if (ch=='-'||ch=='=')
r_str_concatch(str, ch);
else strcat(str, "|");
} else r_str_concatch(str, ch);
} else { /* up */
if (addr < ref->from && addr > ref->to) {
if (ch=='-'||ch=='=')
r_str_concatch(str, ch);
else strcat(str, "|");
} else r_str_concatch(str, ch);
}
if (wide) {
if (ch == '=' || ch == '-')
r_str_concatch(str, ch);
else strcat(str, " ");
}
}
switch (dir) {
case 1: strcat(str, "-> "); break;
case 2: strcat(str, "=< "); break;
default: strcat(str, " "); break;
}
return R_TRUE;
}

View File

@ -4,6 +4,8 @@ DEPS=r_util
include ../config.mk
CFLAGS+=-DCORELIB
foo: ${LIBSO} ${LIBAR} plugins
include ${STATIC_CMD_PLUGINS}

View File

@ -1,8 +1,9 @@
OBJ_DUMMY+=cmd_dummy.o
TARGET_DUMMY=cmd_dummy.${EXT_SO}
ALL_TARGETS+=${TARGET_DUMMY}
STATIC_OBJ+=${OBJ_DUMMY}
TARGET_DUMMY=cmd_dummy.${EXT_SO}
ALL_TARGETS+=${TARGET_DUMMY}
${TARGET_DUMMY}: ${OBJ_DUMMY}
${CC} ${CFLAGS} -o cmd_dummy.${EXT_SO} cmd_dummy.o
${CC} ${CFLAGS} -o ${TARGET_DUMMY} ${OBJ_DUMMY}

View File

@ -881,9 +881,10 @@ static int cmd_anal(void *data, const char *input) {
switch(input[0]) {
case 'h':
if (input[1] && !r_anal_use (&core->anal, input+2))
eprintf("Cannot use '%s' anal plugin.\n", input+2);
else r_anal_list (&core->anal);
if (input[1]) {
if (!r_anal_use (&core->anal, input+2))
eprintf("Cannot use '%s' anal plugin.\n", input+2);
} else r_anal_list (&core->anal);
break;
case 'o':
{
@ -898,11 +899,15 @@ static int cmd_anal(void *data, const char *input) {
core->offset+idx, buf + idx, (len-idx));
}
break;
case 'c':
r_cons_printf ("TODO\n");
break;
default:
r_cons_printf (
"Usage: a[o] [len]\n"
" ah [handle] ; Use this analysis plugin\n"
" ao [len] ; Analyze raw bytes\n");
" ao [len] ; Analyze raw bytes\n"
" ac @ [addr] ; Analyze code (start at addr)\n");
break;
}
if (tbs != core->blocksize)

View File

@ -5,8 +5,9 @@
#ifndef _INCLUDE_R_ANAL_H_
#define _INCLUDE_R_ANAL_H_
#include "r_types.h"
#include "list.h"
#include <r_types.h>
#include <list.h>
#include <r_list.h>
// deprecate this macro?
#define R_ANAL_MAXREG 16
@ -75,11 +76,11 @@ enum {
};
enum {
R_ANAL_BLK_TYPE_NULL = 0,
R_ANAL_BLK_TYPE_HEAD, /* first block */
R_ANAL_BLK_TYPE_BODY, /* conditional jump */
R_ANAL_BLK_TYPE_LAST, /* ret */
R_ANAL_BLK_TYPE_FOOT /* unknown jump */
R_ANAL_BB_TYPE_NULL = 0,
R_ANAL_BB_TYPE_HEAD, /* first block */
R_ANAL_BB_TYPE_BODY, /* conditional jump */
R_ANAL_BB_TYPE_LAST, /* ret */
R_ANAL_BB_TYPE_FOOT /* unknown jump */
};
enum {
@ -97,12 +98,15 @@ enum {
R_ANAL_REFLINE_WIDE = 2,
};
typedef struct r_anal_refline_t {
ut64 from;
ut64 to;
int index;
struct list_head list;
} RAnalysisRefline;
typedef struct r_anal_t {
int bits;
int big_endian;
void *user;
RList *bbs;
struct r_anal_ctx_t *ctx;
struct r_anal_handle_t *cur;
struct list_head anals;
} RAnalysis;
typedef struct r_anal_aop_t {
int type; /* type of opcode */
@ -119,19 +123,13 @@ typedef struct r_anal_aop_t {
ut64 i_dst[R_ANAL_MAXREG]; /* inmediate arguments */
} RAnalysisAop;
typedef struct r_anal_function_t {
ut64 from;
ut64 to;
} RAnalysisFunction;
typedef struct r_anal_t {
int bits;
int big_endian;
void *user;
struct r_anal_ctx_t *ctx;
struct r_anal_handle_t *cur;
struct list_head anals;
} RAnalysis;
typedef struct r_anal_bb_t {
ut64 addr;
ut64 size;
ut64 jump;
ut64 fail;
RList *aops;
} RAnalysisBB;
typedef struct r_anal_ctx_t {
/* TODO: add more info here */
@ -142,6 +140,12 @@ typedef struct r_anal_ctx_t {
struct r_anal_t *anal;
} RAnalysisContext;
typedef struct r_anal_refline_t {
ut64 from;
ut64 to;
int index;
struct list_head list;
} RAnalysisRefline;
//TODO: typedef RAnalysisAopCallback
typedef struct r_anal_handle_t {
@ -150,15 +154,20 @@ typedef struct r_anal_handle_t {
int (*init)(void *user);
int (*fini)(void *user);
// TODO: typedef
int (*aop)(struct r_anal_t *a, struct r_anal_aop_t *aop, ut64 addr, const ut8 *data, int len);
int (*aop)(struct r_anal_t *a, struct r_anal_aop_t *aop,
ut64 addr, const ut8 *data, int len);
struct list_head list;
} RAnalysisHandle;
/* anal.c */
#ifdef R_API
R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal);
R_API struct r_anal_t *r_anal_free(struct r_anal_t *r);
R_API struct r_anal_t *r_anal_new();
R_API RList *r_anal_bb_list_new();
R_API RList *r_anal_aop_list_new();
R_API struct r_anal_t *r_anal_free(struct r_anal_t *r);
R_API void r_anal_bb_list_free(void *bbs);
R_API void r_anal_aop_list_free(void *aops);
R_API struct r_anal_t *r_anal_init(struct r_anal_t *anal);
R_API void r_anal_set_user_ptr(struct r_anal_t *anal, void *user);
R_API int r_anal_add(struct r_anal_t *anal, struct r_anal_handle_t *foo);
R_API int r_anal_list(struct r_anal_t *anal);
@ -167,10 +176,12 @@ R_API int r_anal_set_bits(struct r_anal_t *anal, int bits);
R_API int r_anal_set_big_endian(struct r_anal_t *anal, int boolean);
R_API int r_anal_set_pc(struct r_anal_t *a, ut64 pc);
R_API int r_anal_aop(struct r_anal_t *anal, struct r_anal_aop_t *aop,
ut64 addr, void *data, int len);
ut64 addr, void *data, int len);
/* reflines.c */
R_API struct r_anal_refline_t *r_anal_reflines_get(struct r_anal_t *anal,
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout);
ut64 addr, ut8 *buf, ut64 len, int nlines, int linesout);
R_API int r_anal_reflines_str(struct r_anal_t *anal, struct r_anal_refline_t *list,
ut64 addr, char *str, int opts);
ut64 addr, char *str, int opts);
#endif
#endif

View File

@ -1,6 +1,8 @@
CFLAGS+=-g -Wall
PREFIX?=/usr
all: r2rc
r2rc: r2rc.o emit_x86.o emit_x64.o out.o
gcc -I. out.o r2rc.o emit*.o -o r2rc