mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-01 02:53:22 +00:00
* 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:
parent
a9a4c51132
commit
4c0b8f437b
@ -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"
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2008-2011 pancake<nopcode.org> */
|
||||
|
||||
#include <r_debug.h>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user