mirror of
https://github.com/radareorg/radare2.git
synced 2024-10-09 20:04:49 +00:00
* 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:
parent
4b558bec3b
commit
8081f02601
8
TODO
8
TODO
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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
167
libr/debug/p/drx.c
Normal 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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user