* Fix uninitialized variable in rabin2

* Fix null pointer handling in rbin when no xtr plugin found
* Initial draft code for the x86 debug registers implementation
* Fix avr* command
This commit is contained in:
pancake 2010-10-01 11:10:59 +02:00
parent 4b558bec3b
commit 8081f02601
10 changed files with 206 additions and 34 deletions

8
TODO
View File

@ -59,9 +59,8 @@ TODO edu
TODO pancake
------------
* Import r_vm register values from flags or from r_debug->r_reg
- r_vm must use mmu cache when emulating code
- use the one from r_io? and deprecate vm->mmu_cache?
* Embed RBin inside RCoreFile
* Implement DRX support
* Record trace of register status for each function when running
- r_reg_arena_copy();
{
@ -93,6 +92,9 @@ Bindings
Refactoring
===========
* Import r_vm register values from flags or from r_debug->r_reg
- r_vm must use mmu cache when emulating code
- use the one from r_io? and deprecate vm->mmu_cache?
* Review the r_flags api
* add pipe_to_buffer..not only file descriptors
* r_config set_int and so..simplify

View File

@ -120,7 +120,7 @@ static int rabin_show_main() {
static int rabin_extract(int all) {
char out[512], *ptr;
int i;
int i = 0;
if (all) {
for (i=0; i<bin->narch; i++) {
@ -138,12 +138,16 @@ static int rabin_extract(int all) {
if ((ptr = strrchr (bin->arch[i].file, '/')))
ptr = ptr+1;
else ptr = bin->arch[i].file;
snprintf (out, sizeof (out), "%s.%s_%i", ptr,
bin->arch[i].info->arch, bin->arch[i].info->bits);
if (!r_file_dump (out, bin->curarch->buf->buf, bin->curarch->size)) {
eprintf ("Error extracting %s\n", out);
return R_FALSE;
} else eprintf ("%s created\n", out);
if (bin->arch[i].info == NULL) {
eprintf ("No extract info found.\n");
} else {
snprintf (out, sizeof (out), "%s.%s_%i", ptr,
bin->arch[i].info->arch, bin->arch[i].info->bits);
if (!r_file_dump (out, bin->curarch->buf->buf, bin->curarch->size)) {
eprintf ("Error extracting %s\n", out);
return R_FALSE;
} else eprintf ("%s created\n", out);
}
}
return R_TRUE;
}
@ -447,6 +451,7 @@ static void rabin_list_archs() {
int i;
for (i=0; i<bin->narch; i++) {
if (bin->arch[i].info)
printf ("%s_%i %s (%s)\n", bin->arch[i].info->arch,
bin->arch[i].info->bits, bin->arch[i].file,
bin->arch[i].info->machine);

View File

@ -137,13 +137,13 @@ static int r_bin_extract(RBin *bin, const char* file) {
bin->file = r_file_abspath (file);
list_for_each (pos, &bin->binxtrs) {
RBinXtrPlugin *h = list_entry (pos, RBinXtrPlugin, list);
if (h->check && h->check (bin)) {
if (h->check && h->check (bin))
bin->curxtr = h;
}
}
if (bin->curxtr && bin->curxtr->extract)
n = bin->curxtr->extract (bin);
else {
// TODO XXX: fill bin->arch[0].info!
bin->arch[0].file = strdup (bin->file);
if (!(buf = (ut8*)r_file_slurp (bin->file, &bin->arch[0].size)))
return 0;

View File

@ -6,9 +6,7 @@
#include "dyldcache.h"
static int r_bin_dyldcache_init(struct r_bin_dyldcache_obj_t* bin) {
int len;
len = r_buf_fread_at(bin->b, 0, (ut8*)&bin->hdr, "16c4il", 1);
int len = r_buf_fread_at (bin->b, 0, (ut8*)&bin->hdr, "16c4il", 1);
if (len == -1) {
perror ("read (cache_header)");
return R_FALSE;
@ -62,7 +60,7 @@ struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj
strncpy (ret[i].path, libname, sizeof (ret[j].path));
ret[j].size = libsz;
ret[j].last = 0;
j = j+1;
j++;
//printf("0x%08llx -> %i -> %s\n", liboff, libsz, libname);
}
ret[i].last = 1;
@ -81,7 +79,6 @@ void* r_bin_dyldcache_free(struct r_bin_dyldcache_obj_t* bin) {
struct r_bin_dyldcache_obj_t* r_bin_dyldcache_new(const char* file) {
struct r_bin_dyldcache_obj_t *bin;
ut8 *buf;
if (!(bin = malloc(sizeof(struct r_bin_dyldcache_obj_t))))
return NULL;
memset (bin, 0, sizeof (struct r_bin_dyldcache_obj_t));

View File

@ -28,7 +28,7 @@ static int extract(RBin *bin) {
struct r_bin_dyldcache_lib_t *libs;
int i;
if(!(bin->bin_obj = r_bin_dyldcache_new(bin->file)))
if(!(bin->bin_obj = r_bin_dyldcache_new (bin->file)))
return 0;
libs = r_bin_dyldcache_extract ((struct r_bin_dyldcache_obj_t*)bin->bin_obj);
if (!libs)

View File

@ -1806,7 +1806,7 @@ static int var_cmd(RCore *core, const char *str) {
static void vmimport(RCore *core, int dir) {
struct list_head *pos;
list_for_each(pos, &core->vm->regs) {
struct r_vm_reg_t *r = list_entry(pos, struct r_vm_reg_t, list);
RVmReg *r = list_entry(pos, RVmReg, list);
if (dir) {
r_cons_printf ("ave %s=0x%"PFMT64x"\n", r->name, r->value);
r_cons_printf ("f vm.%s=0x%"PFMT64x"\n", r->name, r->value);
@ -2154,6 +2154,7 @@ static int cmd_anal(void *data, const char *input) {
" ; set register alias\n"
" avr eax ; view register\n"
" avr eax=33 ; set register value\n"
" avr* ; show registers as in flags\n"
" avrt ; list valid register types\n"
"Note: The prefix '\"' quotes the command and does not parses pipes and so\n");
else r_vm_cmd_reg (core->vm, input+2);
@ -2186,6 +2187,7 @@ static int cmd_anal(void *data, const char *input) {
" avr ; show registers\n"
" avx N ; execute N instructions from cur seek\n"
" av- ; restart vm using asm.arch\n"
" av* ; show registers as in flags\n"
" avr eax ; show register eax\n"
" avrr eax ; set return register\n" // TODO .merge avrr and avrc
" avrc eip esp ebp ; set basic cpu registers PC, SP, BP\n"

167
libr/debug/p/drx.c Normal file
View File

@ -0,0 +1,167 @@
#include <r_types.h>
/* -------------------- drx.h ------------------- */
#define DRXN 7
#define DR_STATUS 6
#define DR_CONTROL 7
#define DR_LOCAL_ENABLE_SHIFT 0 /* Extra shift to the local enable bit. */
#define DR_GLOBAL_ENABLE_SHIFT 1 /* Extra shift to the global enable bit. */
#define DR_ENABLE_SIZE 2 /* Two enable bits per debug register. */
/* Fields reserved by Intel. This includes the GD (General Detect
Enable) flag, which causes a debug exception to be generated when a
MOV instruction accesses one of the debug registers.
FIXME: My Intel manual says we should use 0xF800, not 0xFC00. */
#define DR_CONTROL_RESERVED (0xFC00)
#define I386_DR_CONTROL_MASK (~DR_CONTROL_RESERVED)
#define DR_LOCAL_SLOWDOWN (0x100)
#define DR_GLOBAL_SLOWDOWN (0x200)
/* DR7 fields */
/* How many bits to skip in DR7 to get to R/W and LEN fields. */
#define DR_CONTROL_SHIFT 16
/* How many bits in DR7 per R/W and LEN field for each watchpoint. */
#define DR_CONTROL_SIZE 4
#define DR_RW_EXECUTE (0x0) /* Break on instruction execution. */
#define DR_RW_WRITE (0x1) /* Break on data writes. */
#define DR_RW_IORW (0x2) /* Break on I/O reads or writes (not supported (2001) */
#define DR_RW_READ (0x3) /* Break on data reads or writes. */
/* Debug registers' indices. */
#define DR_NADDR 4 /* The number of debug address registers. */
#define DR_STATUS 6 /* Index of debug status register (DR6). */
#define DR_CONTROL 7 /* Index of debug control register (DR7). */
// is ut64 on 64 bitz ?
//#define drxt ut64
#define drxt ut32
#define DR_LEN_1 (0<<2) /* 1-byte region watch or breakpoint. */
#define DR_LEN_2 (1<<2) /* 2-byte region watch. */
#define DR_LEN_4 (3<<2) /* 4-byte region watch. */
#define DR_LEN_8 (2<<2) /* 8-byte region watch (AMD64). */
#define I386_DR_CONTROL_MASK (~DR_CONTROL_RESERVED)
/* unused */
#define I386_DR_VACANT(control, i) \
((control & (3 << (DR_ENABLE_SIZE * (i)))) == 0)
/* local/global */
#define I386_DR_LOCAL_ENABLE(control, i) \
control |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
#define I386_DR_GLOBAL_ENABLE(control, i) \
control |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (i)))
/* enable/disable */
#define I386_DR_ENABLE(control, i) \
control |= (3 << (DR_ENABLE_SIZE * (i)))
#define I386_DR_DISABLE(control, i) \
control &= ~(3 << (DR_ENABLE_SIZE * (i)))
#define I386_DR_SET_RW_LEN(control, i,rwlen) \
do { \
control &= ~(0x0f << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
control |= ((rwlen) << (DR_CONTROL_SHIFT+DR_CONTROL_SIZE*(i))); \
} while (0)
#define I386_DR_GET_RW_LEN(control, i) \
((control >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (i))) & 0x0f)
/* ----------------------------- */
#if 0
options are:
address
length
local/global
type (rwxi)
// DRX CHK
int drx_check() {
return R_TRUE;
}
#endif
int drx_set(drxt *drx, int n, ut64 addr, int len, int rwx, int global) {
ut32 control = drx[DR_CONTROL];
if (n<0 || n>4) {
eprintf ("Invalid DRX index (0-4)\n");
return R_FALSE;
}
switch (len) {
case 1:
len = 0;
break;
case 2:
len = 1<<2;
break;
case 4:
len = 3<<2;
break;
case 8:
len = 2<<2; // AMD64 only
break;
default:
eprintf ("Invalid DRX length\n");
return R_FALSE;
}
I386_DR_SET_RW_LEN (control, n, len);
if (global) {
I386_DR_GLOBAL_ENABLE (control, n);
control |= DR_GLOBAL_SLOWDOWN;
} else {
I386_DR_LOCAL_ENABLE (control, n);
control |= DR_LOCAL_SLOWDOWN;
}
control &= I386_DR_CONTROL_MASK;
drx[n] = addr;
drx[DR_CONTROL] = control;
}
ut64 drx_get(drxt *drx, int n, int *rwx, int *len, int *global) {
int ret = I386_DR_GET_RW_LEN (drx[DR_CONTROL], n);
if (global) *global = drx[DR_CONTROL] & DR_GLOBAL_SLOWDOWN;
if (len) *len = (ret & 0xf)>>2;
if (rwx) *rwx = ret & 0x3;
return (ut64)drx[n];
}
int drx_next(drxt *drx) {
int i;
for(i=0; i<4; i++)
if (!drx[i])
return i;
return -1;
}
void drx_list(drxt *drx) {
ut64 addr;
int i, type, len, g;
for(i=0; i<4; i++) {
addr = drx_get (drx, i, &type, &len, &g);
printf ("DR%d %c%c%c%c 0x%08llx %d\n", i,
g?'g':'l',
(type&DR_RW_READ)? 'r':'-',
(type&DR_RW_WRITE)? 'w':'-',
(type&DR_RW_EXECUTE)? 'x':'-',
addr, len);
}
}
void drx_init(drxt *r) {
memset (r, 0, sizeof (drxt)*DRXN);
}
#if MAIN
int main() {
drxt regs[DRXN];
drx_init (regs);
drx_set (regs, 1, 0x8048000, 1, DR_RW_EXECUTE, 0);
drx_list (regs);
}
#endif

View File

@ -142,19 +142,21 @@ R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str) {
len = strlen (_str)+1;
str = alloca (len);
memcpy (str, _str, len);
memcpy (str, _str, len); // XXX: suboptimal
if (str==NULL || str[0]=='\0') {
/* show all registers */
switch(*str) {
case '*':
r_vm_print (vm, -2);
return 0;
case '\0':
r_vm_print (vm, -1);
return 0;
}
if (str[0]=='o') {
case 'o':
r_vm_cmd_op (vm, str+2);
return 0;
}
strcpy(str, str+1);
switch(str[0]) {
str++;
switch (*str) {
case 'r':
r_vm_setup_ret (vm, str+2);
break;
@ -205,11 +207,11 @@ R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str) {
// avr-*
for(str=str+1;str&&*str==' ';str=str+1);
if (str[0]=='*')
INIT_LIST_HEAD(&vm->regs); // XXX Memory leak
else r_vm_reg_del(vm, str);
INIT_LIST_HEAD (&vm->regs); // XXX Memory leak
else r_vm_reg_del (vm, str);
break;
case 'f':
r_vm_setup_flags(vm, str+2);
r_vm_setup_flags (vm, str+2);
break;
default:
for(;str&&*str==' ';str=str+1);
@ -240,7 +242,7 @@ R_API ut64 r_vm_reg_get(struct r_vm_t *vm, const char *name) {
int len;
if (!name)
return 0LL;
len = strlen(name);
len = strlen (name);
if (name[len-1]==']')
len--;
@ -252,7 +254,6 @@ R_API ut64 r_vm_reg_get(struct r_vm_t *vm, const char *name) {
r_vm_eval(vm, r->get);
//vm_op_eval(r->get);
vm->rec = NULL;
return r->value;
}
return r->value;
}

View File

@ -18,8 +18,7 @@ static ut64 r_vm_get_value(RVm *vm, const char *str) {
ret = r_vm_reg_get (vm, vm->cpu.pc);
arch_aop (ret , config.block, &aop);
return aop.length;
} else // $$
return config.seek;
} else return config.seek; // $$
#endif
}

View File

@ -20,7 +20,6 @@ con.any_key()
con.clear()
print dir(RCons.is_html)
print RCons.is_html.getter(0)
print "IS HTML %d"%int(RCons.is_html)
con.printf(Color_RED + "Hello "+Color_GREEN + "World\n" + Color_RESET)
con.flush();