* Oops. fix ruby plugin build

* Added dummy r_trace r_meta and r_var
  - With readme, dummy code and comments..
This commit is contained in:
pancake 2009-02-12 15:47:13 -08:00
parent 49b637328f
commit 7b96c49110
10 changed files with 1924 additions and 2 deletions

View file

@ -57,6 +57,8 @@
-----------
- Define a way to iterate flags from vala
- We probably need more methods
- support to define relations between flags
(flag hirearchies)
|| hash ||
----------

26
libr/debug/README Normal file
View file

@ -0,0 +1,26 @@
r_debug
=======
Debugger API for radare2
We need to connect multiple pieces...
debugger engine: vm, qemu, bochs, ptrace, mach, w32dbg...
controlflow commands: (should be splitted in two layers)
- continue -- low level
- step -- low level
- trace --- high level one
- ...
the control flow commands depend on other stuff to decide
how to work..this is for example if the arch doesnt supports
continuation, we should provide a step based continue. The
same when a watchpoint is activated and the arch didnt
supports hardware regs for this purpose.
We also need a load/store/dump/restore functions to move the
program from one engine to another (ptrace -> qemu).. we should
provide a way for all this operations between them.

View file

@ -6,7 +6,7 @@ all: lua.so dummy.so ruby.so python.so
python.so:
-${CC} ${CFLAGS} -I/usr/include/python2.5 \
-fPIC -shared -o python.so python.c -lpython
-fPIC -shared -o python.so python.c -lpython >/dev/null 2>&1
lua.so: lua.o
-${CC} ${CFLAGS} -fPIC -shared -o lua.so lua.c -Wl,-R..

View file

@ -52,7 +52,7 @@ static int init(void *user)
ruby_init();
ruby_init_loadpath();
rb_eval_string_protect("require 'irb'", &err);
rb_eval_string_protect("require 'irb'", NULL);
core = user;
rb_RadareCmd = rb_define_class("RadareInternal", rb_cObject);
rb_define_method(rb_RadareCmd, "cmd", radare_ruby_cmd, 1);

47
libr/meta/README Normal file
View file

@ -0,0 +1,47 @@
r_meta
======
enum {
R_META_DATA,
R_META_CODE,
R_META_CODE_XREF,
R_META_DATA_XREF,
R_META_STRING,
R_META_FUNCTION,
R_META_STRUCT,
R_META_COMMENT,
R_META_FOLDER
}
struct r_meta_item_t {
int type;
u64 addr;
u64 size;
char *data;
struct list_head list;
};
struct r_meta_t {
struct list_head comments;
struct list_head xrefs;
};
struct r_meta_t * meta = r_meta_new();
/* get list of xrefs to this addr */
r_meta_xrefs_get(meta, 0x8040400);
r_meta_xrefs_add(meta, 0x8040400, 0x8049030);
r_meta_list(meta, RMetaCallback)
r_meta_add(meta, R_META_CODE_XREF, 100, 200);
r_meta_add_s(meta, R_META_COMMENT, 100, "Hello world");
r_meta_add_s(meta, R_META_STRUCT, 100, "xxi");
r_meta_get(meta, R_META_COMMENT, 0x804800);
r_meta_get_range(meta, R_META_COMMENT, 0x804800, 0x8049000);
// TODO: rethink argument order
r_meta_get_closer(meta, 0x0394, R_META_STRING, R_META_GET_FORWARD);

334
libr/trace/trace.c Normal file
View file

@ -0,0 +1,334 @@
/*
* Copyright (C) 2008
* pancake <youterm.com>
*
* radare is part of the radare project
*
* radare is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* radare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with radare; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "main.h"
#include "code.h"
#include "utils.h"
#include "print.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct list_head traces;
static unsigned int n_traces = 0;
static int trace_changed = 0;
static int trace_tag = -1;
int trace_tag_get()
{
return trace_tag;
}
int trace_tag_set(int id)
{
if (id>=-1&&id<64) {
trace_tag = id;
return 1;
}
return 0;
}
int trace_sort()
{
struct list_head *pos, *pos2;
struct list_head *n, *n2;
int ch=0;
if (trace_changed==0)
return 0;
list_for_each_safe(pos, n, &traces) {
struct trace_t *r = list_entry(pos, struct trace_t, list);
list_for_each_safe(pos2, n2, &traces) {
struct trace_t *r2 = list_entry(pos2, struct trace_t, list);
if ((r != r2) && (r->addr > r2->addr)) {
list_move(pos, pos2);
ch=1;
}
}
}
return trace_changed = ch;
}
struct trace_t *trace_get(u64 addr, int tag)
{
struct list_head *pos;
list_for_each(pos, &traces) {
struct trace_t *h= list_entry(pos, struct trace_t, list);
if (tag != -1 && !(h->tags & (1<<tag)))
continue;
if (h->addr == addr)
return h;
}
return NULL;
}
// num of traces for an address
int trace_times(u64 addr)
{
struct trace_t *t = trace_get(addr, trace_tag);
return t?t->times:0;
}
int trace_count(u64 addr)
{
struct trace_t *t = trace_get(addr, trace_tag);
return t?t->count:0;
}
int trace_index(u64 addr)
{
int idx = -1;
struct list_head *pos;
list_for_each(pos, &traces) {
struct trace_t *h = list_entry(pos, struct trace_t, list);
idx++;
if (h->addr == addr)
return idx;
}
return idx;
}
int trace_set_times(u64 addr, int times)
{
char bytes[16];
struct trace_t *t;
struct list_head *pos;
if (arch_aop == NULL)
return -1;
/* update times counter */
list_for_each(pos, &traces) {
t = list_entry(pos, struct trace_t, list);
if (t->addr == addr) {
t->times = times;
return 1;
}
}
return 0;
}
int trace_add(u64 addr)
{
char bytes[16];
struct trace_t *t;
struct list_head *pos;
if (arch_aop == NULL)
return -1;
if (config_get("trace.dup")) {
/* update times counter */
list_for_each(pos, &traces) {
t = list_entry(pos, struct trace_t, list);
if (t->addr == addr) {
if (trace_tag != -1)
t->tags |= trace_tag;
++(t->times);
}
}
} else {
list_for_each(pos, &traces) {
t = list_entry(pos, struct trace_t, list);
if (t->addr == addr) {
t->count = ++n_traces;
gettimeofday(&(t->tm), NULL);
if (trace_tag != -1)
t->tags |= trace_tag;
return ++(t->times);
}
}
}
t = (struct trace_t *)malloc(sizeof(struct trace_t));
memset(t,'\0',sizeof(struct trace_t));
t->addr = addr;
t->times = 1;
radare_read_at(addr, bytes, 16);
t->opsize = arch_aop(addr, bytes, NULL);
gettimeofday(&(t->tm), NULL);
t->count = ++n_traces;
if (trace_tag != -1)
t->tags |= trace_tag;
trace_changed = 1;
list_add_tail(&(t->list), &traces);
//eprintf("new trace (0x%08x)\n", (unsigned long)addr);
return t->times;
}
u64 trace_range(u64 from, int tag)
{
struct trace_t *h;
u64 last = from;
u64 last2 = 0LL;
while(last != last2) {
last2 = last;
h = trace_get(last, tag);
if (h) {
if (tag != -1 && !(h->tags & (1<<tag)))
continue;
last = last + h->opsize;
}
}
return last;
}
#if 1
u64 trace_next(u64 from, int tag)
{
u64 next = 0xFFFFFFFFFFFFFFFFLL;
struct list_head *pos;
struct trace_t *h;
list_for_each(pos, &traces) {
h = list_entry(pos, struct trace_t, list);
if (tag != -1 && !(h->tags & (1<<tag)))
continue;
if (h->addr > from && h->addr < next)
next = h->addr;
}
if (next == 0xFFFFFFFFFFFFFFFFLL)
return 0LL;
return next;
}
#endif
#if 0
/* buggy version */
u64 trace_next(u64 from)
{
u64 next;
int next_init = 0;
struct list_head *pos;
struct trace_t *h;
list_for_each(pos, &traces) {
h = list_entry(pos, struct trace_t, list);
if (!next_init) {
if (h->addr > from && h->addr < next) {
next = h->addr;
next_init = 1;
}
continue;
}
if (h->addr > from && h->addr < next)
next = h->addr;
}
if (next_init == 0)
return NULL;
return next;
}
#endif
void trace_show(int plain, int tag)
{
u64 from = 0LL;
u64 last;
char bytes[32];
char opcode[64];
struct list_head *pos;
struct trace_t *h;
if (tag != -1)
eprintf("Displaying tag: %d\n", tag+1);
trace_sort();
opcode[0]='\0';
/* get the lower address */
list_for_each(pos, &traces) {
h = list_entry(pos, struct trace_t, list);
if (from == 0LL)
from = h->addr;
if (h->addr < from)
from = h->addr;
if (tag != -1 && !(h->tags & (1<<tag)))
continue;
switch(plain) {
case 1:
cons_printf("0x%08llx %d %d tags=%08llx\n",
h->addr, h->times, h->count, h->tags);
break;
case 2:
config.verbose=0;
cons_printf("%03d %03d ", h->times, h->count);
sprintf(opcode, "pd 1 @ 0x%08llx", h->addr);
radare_cmd_raw(opcode, 0);
//radare_read_at(h->addr, bytes, 32);
//udis_arch_string(config.arch, opcode, bytes, config.endian, h->addr, 32, 0);
break;
}
}
if (plain>0)
return;
while(from) {
last = trace_range(from, tag);
if (last == from)
break;
// TODO: show timestamps
if (plain==0)
cons_printf("0x%08llx - 0x%08llx\n", from, last);
else cons_printf("ar+ 0x%08llx 0x%08llx\n", from, last);
from = trace_next(last, tag);
cons_flush();
}
}
void trace_init()
{
INIT_LIST_HEAD(&traces);
}
void trace_reset()
{
struct list_head *pos;
struct trace_t *h;
list_for_each(pos, &traces) {
h = list_entry(pos, struct trace_t, list);
free(h);
}
INIT_LIST_HEAD(&traces);
}
int trace_get_between(u64 from, u64 to)
{
int ctr = 0;
struct list_head *pos;
struct trace_t *h;
/* get the lower address */
list_for_each(pos, &traces) {
h = list_entry(pos, struct trace_t, list);
if (trace_tag != -1 && !(h->tags & (1<<trace_tag)))
continue;
if (h->addr >= from && h->addr <=to)
ctr++;
}
return ctr;
}

9
libr/var/README Normal file
View file

@ -0,0 +1,9 @@
r_vars_add()
...
Contains old:
vars.c
data.c
analyze.c - related code var analysis (after analyze a function
return a list of accesses to local and lgobal vars)
See tmp/ fmi

1050
libr/var/tmp/analyze.c Normal file

File diff suppressed because it is too large Load diff

143
libr/var/tmp/data.c Normal file
View file

@ -0,0 +1,143 @@
/*
* Copyright (C) 2008
* pancake <youterm.com>
*
* radare is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* radare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with radare; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "main.h"
#include "code.h"
#include "data.h"
#include "undo.h"
#include "flags.h"
#include "arch/csr/dis.h"
#include "arch/arm/disarm.h"
#include "arch/ppc/ppc_disasm.h"
#include "arch/m68k/m68k_disasm.h"
#include "arch/x86/udis86/types.h"
#include "arch/x86/udis86/extern.h"
#include "list.h"
struct reflines_t *reflines = NULL;
static struct list_head vartypes;
/* variables */
void data_comment_init(int new)
{
INIT_LIST_HEAD(&(vartypes));
}
int data_var_type_add(const char *typename, int size, const char *fmt)
{
struct var_type_t *d = (struct var_type_t *)
malloc(sizeof(struct var_type_t));
strncpy(d->name, typename, sizeof(d->name));
strncpy(d->fmt, fmt, sizeof(d->fmt));
d->size = size;
list_add(&(d->list), &vartypes);
return 0;
}
int data_var_type_del(const char *typename)
{
struct list_head *pos;
u64 ret = 0;
if (*typename==' ')typename=typename+1;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
if (!strcmp(typename, d->name)) {
list_del(&(d->list));
return 1;
}
}
return 0;
}
int data_var_type_list()
{
struct list_head *pos;
u64 ret = 0;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
cons_printf("%s %d %s\n", d->name, d->size, d->fmt);
}
return ret;
}
const char *data_var_type_get(const char *datatype)
{
struct list_head *pos;
u64 ret = 0;
list_for_each(pos, &vartypes) {
struct var_type_t *d = (struct var_type_t *)list_entry(pos, struct var_type_t, list);
//eprintf("---(%s)(%s)\n", d->name, datatype);
if (!strcmp(datatype, d->name))
return d;
}
return NULL;
}
int data_var_help()
{
cons_printf(
"Usage: Cv [name] [size] [pm-format-string]\n"
" Cv int 4 d ; define 'int' type\n"
" Cv- int ; remove 'int' var type\n"
" Cv float 4 f\n");
return 0;
}
int data_var_cmd(const char *str)
{
int len;
char *vstr;
char *arg, *arg2;
STRALLOC(vstr, str, len);
if (*str==' ')str=str+1;
switch(*str) {
case '?':
return data_var_help();
case '\0':
/* list var types */
data_var_type_list();
break;
case '-':
data_var_type_del(str+1);
break;
default:
arg = strchr(str, ' ');
if (arg==NULL)
return data_var_help();
*arg='\0'; arg=arg+1;
arg2 = strchr(arg, ' ');
if (arg2==NULL)
return data_var_help();
*arg2='\0'; arg2=arg2+1;
data_var_type_add(str, atoi(arg), arg2);
break;
}
return 0;
}

311
libr/var/tmp/vars.c Normal file
View file

@ -0,0 +1,311 @@
/* Copyleft 2009 - pancake<AT>youterm.com */
#include "main.h"
#include "list.h"
int var_add(u64 addr, u64 eaddr, int delta, int type, const char *vartype, const char *name, int arraysize);
// this can be nested inside the function_t which is not defined..
#if 0
struct function_t {
char name[128];
int framesize;
struct list_head ranges;
struct list_head vars;
};
#endif
static struct list_head vars;
/* variable types */
enum {
VAR_T_GLOBAL,
VAR_T_LOCAL,
VAR_T_ARG,
VAR_T_ARGREG
};
struct var_xs_t {
u64 addr;
int set;
struct list_head list;
};
struct var_t {
int type; /* global, local... */
u64 addr; /* address where it is used */
u64 eaddr; /* address where it is used */
int delta; /* */
int arraysize; /* size of array var in bytes , 0 is no-array */
char name[128];
char vartype[128];
struct list_head access; /* list of accesses for this var */
struct list_head list;
};
int var_add(u64 addr, u64 eaddr, int delta, int type, const char *vartype, const char *name, int arraysize)
{
struct var_t *var = (struct var_t *)malloc(sizeof(struct var_t));
/* TODO: check of delta inside funframe */
if (strchr(name, ' ') || strchr(vartype,' ')) {
eprintf("Invalid name/type\n");
return 0;
}
strncpy(var->name, name, sizeof(var->name));
strncpy(var->vartype, vartype, sizeof(var->vartype));
var->delta = delta;
var->type = type;
var->addr = addr;
var->eaddr = eaddr;
var->arraysize = arraysize;
INIT_LIST_HEAD(&(var->access));
list_add(&(var->list), &vars);
return 1;
}
int var_add_access(u64 addr, int delta, int type, int set)
{
struct list_head *pos;
struct var_t *v;
int reloop = 0;
_reloop:
list_for_each(pos, &vars) {
v = (struct var_t *)list_entry(pos, struct var_t, list);
if (addr >= v->addr) {
//if (!strcmp(name, v->name)) {
if (delta == v->delta && type == v->type) {
struct var_xs_t *xs = (struct var_xs_t *)malloc(sizeof(struct var_xs_t));
xs->addr = addr;
xs->set = set;
//eprintf("==> %llx\n", addr);
/* add var access here */
list_add(&(xs->list), &(v->access));
return 1;
}
}
}
/* automatic init */
/* detect function in CF list */
{
u64 from = 0LL, to = 0LL;
if ( data_get_fun_for(addr, &from, &to) ) {
char varname[32];
if (delta < 0) {
delta = -delta;
sprintf(varname, "arg_%d", delta);
} else sprintf(varname, "var_%d", delta);
//eprintf("0x%08llx: NEW LOCAL VAR %d\n", from, delta);
var_add(from, to, delta, VAR_T_LOCAL, "int32", varname, 1);
if (reloop) {
#warning THIS IS BUGGY: SHOULD NEVER HAPPEN
eprintf("LOOPING AT 0x%08llx NOT ADDING AN ACCESS\n", addr);
return 0;
}
reloop=1;
goto _reloop;
return var_add_access(addr, delta, type, set);
} else eprintf("Cannot find bounding function at 0x%08llx\n", addr);
}
return 0;
}
const char *var_type_str(int fd)
{
switch(fd) {
case VAR_T_GLOBAL: return "global";
case VAR_T_LOCAL: return "local";
case VAR_T_ARG: return "arg";
case VAR_T_ARGREG: return "fastarg";
}
return "(?)";
}
u32 var_dbg_read(int delta)
{
/* XXX: EBP ONLY FOR X86 */
u32 ret;
u64 foo = get_offset("ebp");
foo-=delta;
radare_read_at(foo, (u8*)&ret, 4);
return ret;
}
void print_mem(u64 addr, const u8 *buf, u64 len, const char *fmt, int endian);
int var_print_value(struct var_t *v)
{
struct var_type_t *t = data_var_type_get(v->vartype);
if (t == NULL) {
u32 value = var_dbg_read(v->delta);
// TODO: use var type to
cons_printf("%x", value);
} else {
u8 buf[1024];
int verbose = config.verbose;
int size = v->arraysize * t->size;
u64 foo = get_offset("ebp");
foo -= v->delta;
radare_read_at(foo, buf, size);
//eprintf("PRINT_MEM(%llx,%d,%s)\n", foo, size, t->fmt);
config.verbose = 0;
print_mem(foo, buf, size, t->fmt, config.endian);
config.verbose = verbose;
}
return 0;
}
/* CFV */
int var_list_show(u64 addr)
{
char buf[256];
struct list_head *pos, *pos2;
struct var_t *v;
struct var_xs_t *x;
list_for_each(pos, &vars) {
v = (struct var_t *)list_entry(pos, struct var_t, list);
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
u32 value = var_dbg_read(v->delta);
if (v->arraysize>1)
cons_printf("%s %s %s[%d] = ", var_type_str(v->type), v->vartype, v->arraysize, v->name);
else cons_printf("%s %s %s = ", var_type_str(v->type), v->vartype, v->name);
var_print_value(v);
/* TODO: detect pointer to strings and so on */
if (string_flag_offset(buf, value, 0))
cons_printf(" ; points to: %s\n", buf);
else cons_newline();
}
}
return 0;
}
/* 0,0 to list all */
int var_list(u64 addr, int delta)
{
struct list_head *pos, *pos2;
struct var_t *v;
struct var_xs_t *x;
list_for_each(pos, &vars) {
v = (struct var_t *)list_entry(pos, struct var_t, list);
if (addr == 0 || (addr >= v->addr && addr <= v->eaddr)) {
cons_printf("0x%08llx - 0x%08llx type=%s type=%s name=%s delta=%d array=%d\n",
v->addr, v->eaddr, var_type_str(v->type),
v->vartype, v->name, v->delta, v->arraysize);
list_for_each_prev(pos2, &v->access) {
x = (struct var_xs_t *)list_entry(pos2, struct var_xs_t, list);
cons_printf(" 0x%08llx %s\n", x->addr, x->set?"set":"get");
}
}
}
return 0;
}
int var_init()
{
INIT_LIST_HEAD(&vars);
data_var_type_add("char", 1, "b");
data_var_type_add("byte", 1, "b");
data_var_type_add("int", 4, "d");
data_var_type_add("int32", 4, "d");
data_var_type_add("dword", 4, "x");
data_var_type_add("float", 4, "f");
}
int var_help()
{
eprintf("Try Cv?\n");
eprintf(" Cv 12 int buffer[3]\n");
eprintf(" Cv 12 byte buffer[1024]\n");
}
int var_cmd_help()
{
eprintf("Try CF[aAv][gs] [delta]\n");
eprintf(" CFag 0 = arg0 get\n");
eprintf(" CFvs 12 = var12 set\n");
eprintf("a = arg, A = fastarg, v = var\n");
}
int var_cmd(const char *str)
{
char *p,*p2,*p3;
int type, delta, len = strlen(str)+1;
p = alloca(len);
memcpy(p, str, len);
str = p;
switch(*str) {
case 'V': // show vars in human readable format
return var_list_show(config.seek);
case 'v': // frame variable
case 'a': // stack arg
case 'A': // fastcall arg
// XXX nested dup
switch(*str) {
case 'v': type = VAR_T_LOCAL; break;
case 'a': type = VAR_T_ARG; break;
case 'A': type = VAR_T_ARGREG; break;
}
/* Variable access CFvs = set fun var */
switch(str[1]) {
case '\0': return var_list(0, 0);
case '.': return var_list(config.seek, 0);
case 's': return var_add_access(config.seek, atoi(str+2), type, 1);
case 'g': return var_add_access(config.seek, atoi(str+2), type, 0);
}
str = str+1;
if (str[0]==' ')str=str+1;
delta = atoi(str);
p = strchr(str, ' ');
if (p==NULL)
return var_cmd_help();
p[0]='\0'; p=p+1;
p2 = strchr(p, ' ');
if (p2==NULL)
return var_help();
p2[0]='\0'; p2=p2+1;
p3 = strchr(p2,'[');
if (p3 != NULL) {
p3[0]='\0';
p3=p3+1;
}
var_add(config.seek, config.seek, delta, type, p, p2, p3?atoi(p3):0);
break;
default:
var_help();
break;
}
return 0;
}
#if 0
-- function boundaries are used to limit variables life-cycle --
// global vars are handled as flags??
// "CV 0x8049200 x global_counter
// local vars
// types: glar: g=global, l=local, a=arg, r=argreg
Cv l d i @ 0x8048200
/* using code analysis we can identify local var accesses */
f.ex:
; Set var0
0x4a13c014, mov [ebp-0x34], eax
; set name for variable accessed.
Cvn counter @ 0x4a13c014
stack frame {
var1 { offset, size, type, name }
var2 { offset, size, type, name }
}
// how to track a variable
#endif