* Added 'pw' and 'pq' commands to print 32bit and 64bit hex values

* Autocomplete 'dcu' argument
* Analyze [pc+delta] mov and lea opcodes on x86-64
  - Resolves indirect string pointers for ObjectiveC binaries
* Handle UCALL in dso
* Fix x86-64 register profile for OSX
* Implement r_mem_get_num()
* Various fixes in 'pf' command
This commit is contained in:
pancake 2011-06-09 01:20:02 +02:00
parent a9a4c51132
commit 4c0b8f437b
11 changed files with 129 additions and 45 deletions

View File

@ -1594,6 +1594,12 @@ static int cmd_print(void *data, const char *input) {
} else eprintf ("ERROR: Cannot malloc %d bytes\n", size);
}
break;
case 'w':
r_print_hexdump (core->print, core->offset, core->block, len, 32, 4);
break;
case 'q':
r_print_hexdump (core->print, core->offset, core->block, len, 64, 8);
break;
case 'D':
case 'd':
switch (input[1]) {
@ -1824,6 +1830,7 @@ static int cmd_print(void *data, const char *input) {
" pb [len] bitstream of N bytes\n"
" pd[ilf] [l] disassemble N opcodes (see pd?)\n"
" pD [len] disassemble N bytes\n"
" p[w|q] [len] word (32), qword (64) value dump\n"
" po [len] octal dump of N bytes\n"
" pc [len] output C format\n"
" pf [fmt] print formatted data\n"

View File

@ -63,7 +63,7 @@ R_API RCore *r_core_new() {
#define CMDS (sizeof (radare_argv)/sizeof(const char*))
static const char *radare_argv[] = {
"?",
"dH", "ds", "dso", "dsl", "dc", "dd", "dm", "db", "dp", "dr",
"dH", "ds", "dso", "dsl", "dc", "dd", "dm", "db", "dp", "dr", "dcu",
"S",
"s", "s+", "s++", "s-", "s--", "s*", "sa", "sb", "sr",
"!", "!!",
@ -163,13 +163,15 @@ printf ("FILEN %d\n", n);
} else
if ((!memcmp (line->buffer.data, "s ", 2)) ||
(!memcmp (line->buffer.data, "b ", 2)) ||
(!memcmp (line->buffer.data, "dcu ", 4)) ||
(!memcmp (line->buffer.data, "/v ", 3)) ||
(!memcmp (line->buffer.data, "f ", 2)) ||
(!memcmp (line->buffer.data, "fr ", 3)) ||
(!memcmp (line->buffer.data, "/a ", 3)) ||
(!memcmp (line->buffer.data, "? ", 2))) {
int n, i = 0;
int sdelta = (line->buffer.data[1]==' ')?2:3;
int sdelta = (line->buffer.data[1]==' ')?2:
(line->buffer.data[2]==' ')?3:4;
n = strlen (line->buffer.data+sdelta);
r_list_foreach (core->flags->flags, iter, flag) {
if (!memcmp (flag->name, line->buffer.data+sdelta, n)) {

View File

@ -143,6 +143,42 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
if (core->inc == 0)
core->inc = ret;
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
{
RAnalValue *src;
switch (analop.type) {
case R_ANAL_OP_TYPE_MOV:
src = analop.src[0];
if (src && src->memref>0 && src->reg) {
if (core->anal->reg && core->anal->reg->name) {
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
RAnalValue *dst = analop.dst;
if (!strcmp (src->reg->name, pc)) {
RFlagItem *item;
ut8 b[8];
ut64 ptr = idx+addr+src->delta+analop.length;
ut64 off = 0LL;
r_core_read_at (core, ptr, b, src->memref);
off = r_mem_get_num (b, src->memref, 1);
item = r_flag_get_i (core->flags, off);
r_cons_printf ("; MOV %s = [0x%"PFMT64x"] = 0x%"PFMT64x" %s\n",
dst->reg->name, ptr, off, item?item->name: "");
}
}
}
break;
case R_ANAL_OP_TYPE_LEA:
src = analop.src[0];
if (src && src->reg && core->anal->reg && core->anal->reg->name) {
const char *pc = core->anal->reg->name[R_REG_NAME_PC];
RAnalValue *dst = analop.dst;
if (dst && dst->reg && !strcmp (src->reg->name, pc)) {
r_cons_printf ("; %s = 0x%"PFMT64x"\n",
dst->reg->name,
idx+addr+src->delta);
}
}
}
}
// Show xrefs
if (show_xrefs) {
RList *xrefs;

View File

@ -266,7 +266,8 @@ R_API int r_debug_step_over(RDebug *dbg, int steps) {
ut64 pc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]);
dbg->iob.read_at (dbg->iob.io, pc, buf, sizeof (buf));
r_anal_op (dbg->anal, &op, pc, buf, sizeof (buf));
if (op.type & R_ANAL_OP_TYPE_CALL) {
if (op.type & R_ANAL_OP_TYPE_CALL
|| op.type & R_ANAL_OP_TYPE_UCALL) {
ut64 bpaddr = pc + op.length;
r_bp_add_sw (dbg->bp, bpaddr, 1, R_BP_PROT_EXEC);
ret = r_debug_continue (dbg);

View File

@ -499,15 +499,13 @@ static const char *r_debug_native_reg_profile(RDebug *dbg) {
"=a1 rbx\n"
"=a2 rcx\n"
"=a3 rdx\n"
"# no profile defined for x86-64\n"
"gpr rax .64 0 0\n"
"gpr rbx .64 8 0\n"
"gpr rcx .64 16 0\n"
"gpr rdx .64 24 0\n"
"gpr rdi .64 32 0\n"
"gpr rsi .64 40 0\n"
"gpr rbp .64 48 0\n"
// gap?
"gpr rax .64 8 0\n"
"gpr rbx .64 16 0\n"
"gpr rcx .64 24 0\n"
"gpr rdx .64 32 0\n"
"gpr rdi .64 40 0\n"
"gpr rsi .64 48 0\n"
"gpr rbp .64 56 0\n"
"gpr rsp .64 64 0\n"
"gpr r8 .64 72 0\n"
"gpr r9 .64 80 0\n"
@ -531,7 +529,9 @@ static const char *r_debug_native_reg_profile(RDebug *dbg) {
"drx dr7 .32 28 0\n"
#endif
);
#elif __x86_64__
#elif __x86_64__
// XXX
//&& __linux__
return strdup (
"=pc rip\n"
"=sp rsp\n"

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2008-2011 pancake<nopcode.org> */
#include <r_debug.h>

View File

@ -177,6 +177,7 @@ R_API int r_buf_write_at(RBuffer *b, ut64 addr, const ut8 *buf, int len);
R_API int r_buf_fwrite_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n);
R_API void r_buf_free(RBuffer *b);
R_API ut64 r_mem_get_num(ut8 *b, int size, int endian);
R_API struct r_mem_pool_t* r_mem_pool_deinit(struct r_mem_pool_t *pool);
R_API struct r_mem_pool_t *r_mem_pool_new(int nodesize, int poolsize, int poolcount);
R_API struct r_mem_pool_t *r_mem_pool_free(struct r_mem_pool_t *pool);

View File

@ -19,7 +19,7 @@ static void print_format_help(RPrint *p) {
" q - quadword (8 bytes)\n"
" p - pointer reference\n"
" d - 0x%%08x hexadecimal value\n"
" X - 0x%%08x hexadecimal value and flag (fd @ addr)\n"
" x - 0x%%08x hexadecimal value and flag (fd @ addr)\n"
" z - \\0 terminated string\n"
" Z - \\0 terminated wide string\n"
" s - pointer to string\n"
@ -37,7 +37,7 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
const char *arg = fmt;
const char *argend = arg+strlen (fmt);
char namefmt[8];
ut64 addr = 0, seeki = 0;;
ut64 addr = 0, addr64 = 0, seeki = 0;;
int viewflags = 0;
nargs = endian = i = j = 0;
@ -92,7 +92,11 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
if (endian)
addr = (*(buf+i))<<24 | (*(buf+i+1))<<16 | *(buf+i+2)<<8 | *(buf+i+3);
else addr = (*(buf+i+3))<<24 | (*(buf+i+2))<<16 | *(buf+i+1)<<8 | *(buf+i);
if (endian)
addr64 = (ut64)(*(buf+i))<<56 | (ut64)(*(buf+i+1))<<48 | (ut64)*(buf+i+2)<<40 | (ut64)(*(buf+i+3))<<32
| (*(buf+i+4))<<24 | (*(buf+i+5))<<16 | *(buf+i+6)<<8 | *(buf+i+7);
else addr64 = ((ut64)(*(buf+i+7)))<<56 | (ut64)(*(buf+i+6))<<48 | (ut64)(*(buf+i+5))<<40 | (ut64)(*(buf+i+4))<<32
| (*(buf+i+3))<<24 | (*(buf+i+2))<<16 | *(buf+i+1)<<8 | *(buf+i);
tmp = *arg;
feed_me_again:
if (tmp == 0 && last != '*')
@ -151,15 +155,16 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
case 'e': {
double doub;
memcpy (&doub, buf+i, sizeof (double));
p->printf ("%e = ", doub);
p->printf ("(double)");
p->printf ("0x%08"PFMT64x" = (double) ", seeki);
p->printf ("%e", doub);
i += 8;
}
break;
case 'q':
p->printf ("0x%08"PFMT64x" = ", seeki);
p->printf ("(qword)");
p->printf ("(qword) ");
i += 8;
p->printf ("0x%08"PFMT64x" ", addr64);
break;
case 'b':
p->printf ("0x%08"PFMT64x" = ", seeki);
@ -189,10 +194,10 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
break;
case 'd':
p->printf ("0x%08"PFMT64x" = ", seeki);
p->printf ("0x%08"PFMT64x" ", addr);
p->printf ("%"PFMT64d" ", addr);
i += 4;
break;
case 'X': {
case 'x': {
ut32 addr32 = (ut32)addr;
//char buf[128];
p->printf ("0x%08"PFMT64x" = ", seeki);

View File

@ -201,9 +201,11 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
const char *pre = "";
if (step<1) step = 1;
switch(base) {
switch (base) {
case 8: fmt = "%03o"; pre = " "; break;
case 10: fmt = "%03d"; pre = " "; break;
case 32: fmt = "0x%08x "; pre = " "; break;
case 64: fmt = "0x%016x "; pre = " "; break;
}
// TODO: Use base to change %03o and so on
@ -213,11 +215,10 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
return;
}
inc = 2 + (int)((p->width-14)/4);
if (inc%2) inc++;
inc = 16;
inc = p->cols;
if (base==64) inc = p->cols/1.2;
if (base<32)
if (p->flags & R_PRINT_FLAGS_HEADER) {
ut32 opad = (ut32)(addr >> 32);
p->printf (" offset ");
@ -241,14 +242,26 @@ R_API void r_print_hexdump(RPrint *p, ut64 addr, const ut8 *buf, int len, int ba
p->interrupt = 0;
for (i=0; !p->interrupt && i<len; i+=inc) {
r_print_addr (p, addr+(i*step));
for (j=i;j<i+inc;j++) {
for (j=i; j<i+inc; j++) {
if (j>=len) {
if (j%2) p->printf (" ");
else p->printf (" ");
p->printf (j%2?" ":" ");
continue;
}
r_print_byte (p, fmt, j, buf[j]);
if (j%2) p->printf (" ");
if (base==32) {
ut32 n;
memcpy (&n, buf+j, sizeof (n));
p->printf ("0x%08x ", n);
j+=3;
} else
if (base==64) {
ut64 n;
memcpy (&n, buf+j, sizeof (n));
j+=4;
p->printf ("0x%016"PFMT64x" ", n);
} else {
r_print_byte (p, fmt, j, buf[j]);
if (j%2) p->printf (" ");
}
}
p->printf (" ");
for (j=i; j<i+inc; j++) {

View File

@ -105,6 +105,25 @@ src |__________|_________|
r_mem_copybits (dst, src, nbits);
}
R_API ut64 r_mem_get_num(ut8 *b, int size, int endian) {
ut16 n16;
ut32 n32;
ut64 n64;
switch (size) {
case 1: return b[0];
case 2:
r_mem_copyendian (&n16, b, 2, endian);
return (ut64)n16;
case 4:
r_mem_copyendian (&n32, b, 4, endian);
return (ut64)n32;
case 8:
r_mem_copyendian (&n64, b, 8, endian);
return (ut64)n64;
}
return 0LL;
}
// TODO: SEE: R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) { .. dupped code?
R_API int r_mem_set_num (ut8 *dest, int dest_size, ut64 num, int endian) {
int num4;

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2007-2010 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
#include "r_util.h"
@ -15,7 +15,7 @@
R_API ut64 r_num_htonq(ut64 value) {
ut64 ret = value;
#if LIL_ENDIAN
r_mem_copyendian((ut8*)&ret, (ut8*)&value, 8, 0);
r_mem_copyendian ((ut8*)&ret, (ut8*)&value, 8, 0);
#endif
return ret;
}
@ -61,7 +61,7 @@ R_API ut64 r_num_get(RNum *num, const char *str) {
char lch, len;
ut64 ret = 0LL;
for (;str[0]==' ';) str = str+1;
for (; *str==' '; ) str++;
/* resolve string with an external callback */
if (num && num->callback) {
@ -74,37 +74,37 @@ R_API ut64 r_num_get(RNum *num, const char *str) {
return (ut64)str[1];
if (str[0]=='0' && str[1]=='x') {
sscanf(str, "0x%"PFMT64x"", &ret);
sscanf (str, "0x%"PFMT64x"", &ret);
} else {
len = strlen (str);
lch = str[len>0?len-1:0];
switch (lch) {
case 'h': // hexa
sscanf(str, "%"PFMT64x"", &ret);
sscanf (str, "%"PFMT64x"", &ret);
break;
case 'o': // octal
sscanf (str, "%"PFMT64o"", &ret);
break;
case 'b': // binary
ret = 0;
for(j=0,i=strlen(str)-2;i>=0;i--,j++) {
for (j=0, i=strlen (str)-2; i>=0; i--, j++) {
if (str[i]=='1') ret|=1<<j;
else if (str[i]!='0') break;
}
break;
default:
sscanf(str, "%"PFMT64d"", &ret);
sscanf (str, "%"PFMT64d"", &ret);
break;
case 'K': case 'k':
sscanf(str, "%"PFMT64d"", &ret);
sscanf (str, "%"PFMT64d"", &ret);
ret *= 1024;
break;
case 'M': case 'm':
sscanf(str, "%"PFMT64d"", &ret);
sscanf (str, "%"PFMT64d"", &ret);
ret *= 1024*1024;
break;
case 'G': case 'g':
sscanf(str, "%"PFMT64d"", &ret);
sscanf (str, "%"PFMT64d"", &ret);
ret *= 1024*1024*1024;
break;
}
@ -199,7 +199,6 @@ R_API ut64 r_num_math(RNum *num, const char *str) {
if (num != NULL)
num->value = ret;
return ret;
}
@ -222,9 +221,10 @@ R_API int r_num_to_bits (char *out, ut64 num) {
else if (num&0xff00) size = 16;
else if (num&0xff) size = 8;
if (out) {
for (i=0;i<size;i++)
out[size-1-i]=(num>>i&1)?'1':'0';
for (i=0; i<size; i++)
out[size-1-i] = (num>>i&1)? '1': '0';
out[size]='\0'; //Maybe not nesesary?
}
return size;
}