/* radare - LGPL - Copyright 2007-2011 pancake */ #include "r_cons.h" #include "r_util.h" #include "r_print.h" static void print_format_help(RPrint *p) { p->printf ( "Usage: pf [times][format] [arg0 arg1]\n" "Example: pf 10xiz pointer length string\n" "Example: pf {array_size}b @ array_base\n" " e - temporally swap endian\n" //" D - double (8 bytes)\n" " f - float value\n" " b - one byte \n" " B - show 10 first bytes of buffer\n" // B must be for binary ?? " i - %%i integer value (4 bytes)\n" " w - word (16 bit hexa)\n" " 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" " z - \\0 terminated string\n" " Z - \\0 terminated wide string\n" " s - pointer to string\n" " t - unix timestamp string\n" " * - next char is pointer\n" " . - skip 1 byte\n"); } /* TODO: needs refactoring */ R_API void r_print_format(struct r_print_t *p, ut64 seek, const ut8* buf, int len, const char *fmt) { unsigned char buffer[256]; int nargs, i, j, idx, times, otimes, endian; char *args, *bracket, tmp, last = 0; const char *arg = fmt; const char *argend = arg+strlen(fmt); ut64 addr = 0; char namefmt[8]; nargs = endian = i = j = 0; while (*arg && *arg==' ') arg++; /* get times */ otimes = times = atoi (arg); if (times > 0) while ((*arg>='0'&&*arg<='9')) arg++; bracket = strchr (arg,'{'); if (bracket) { char *end = strchr (arg,'}'); if (end == NULL) { eprintf ("No end bracket. Try pm {ecx}b @ esi\n"); return; } *end='\0'; times = r_num_math (NULL, bracket+1); arg = end + 1; } if (arg[0]=='\0') { print_format_help (p); return; } /* get args */ args = strchr (arg, ' '); if (args) { int l=0, maxl = 0; argend = args; args = strdup (args+1); nargs = r_str_word_set0 (args+1); if (nargs == 0) R_FREE (args); for (i=0;imaxl) maxl = len; } l++; sprintf (namefmt, "%%%ds : ", maxl); } /* go format */ i = 0; if (times==0) otimes = times = 1; for(;times;times--) { // repeat N times const char * orig = arg; if (otimes>1) p->printf ("0x%08"PFMT64x" [%d] {\n", seek+i, otimes-times); for(idx=0;argprintf (namefmt, r_str_word_get0(args, idx)); /* cmt chars */ switch (tmp) { #if 0 case 'n': // enable newline j ^= 1; continue; #endif #if 0 case 't': /* unix timestamp */ D cons_printf("0x%08x = ", config.seek+i); { /* dirty hack */ int oldfmt = last_print_format; ut64 old = config.seek; radare_seek(config.seek+i, SEEK_SET); radare_read(0); print_data(config.seek+i, "8", buf+i, 4, FMT_TIME_UNIX); last_print_format=oldfmt; radare_seek(old, SEEK_SET); } break; #endif case 'e': { double doub; memcpy (&doub, buf+i, sizeof (double)); p->printf ("%e = ", doub); p->printf ("(double)"); i+=8; } break; case 'q': p->printf ("0x%08x = ", seek+i); p->printf ("(qword)"); i+=8; break; case 'b': p->printf ("0x%08x = ", seek+i); p->printf ("%d ; 0x%02x ; '%c' ", buf[i], buf[i], IS_PRINTABLE(buf[i])?buf[i]:0); i++; break; case 'B': memset(buffer, '\0', 255); if (!p->iob.read_at) { printf ("(cannot read memory)\n"); break; } else p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248); p->printf ("0x%08x = ", seek+i); for (j=0;j<10;j++) p->printf ("%02x ", buf[j]); p->printf(" ... ("); for (j=0;j<10;j++) if (IS_PRINTABLE (buf[j])) p->printf("%c", buf[j]); p->printf(")"); i+=4; break; case 'i': p->printf("0x%08x = ", seek+i); p->printf("%d", addr); i+=4; break; case 'd': p->printf("0x%08x = ", seek+i); p->printf("0x%08x ", addr); i+=4; break; case 'X': { ut32 addr32 = (ut32)addr; //char buf[128]; p->printf ("0x%08x = ", seek+i); p->printf ("0x%08"PFMT64x" ", addr32); //if (string_flag_offset(buf, (ut64)addr32, -1)) // p->printf("; %s", buf); i+=4; } break; case 'w': case '1': // word (16 bits) p->printf ("0x%08x = ", seek+i); if (endian) addr = (*(buf+i))<<8 | (*(buf+i+1)); else addr = (*(buf+i+1))<<8 | (*(buf+i)); p->printf ("0x%04x ", addr); break; case 'z': // zero terminated string p->printf ("0x%08x = ", seek+i); for (;buf[i]&&iprintf ("%c", buf[i]); else p->printf ("."); } break; case 'Z': // zero terminated wide string p->printf ("0x%08x = ", seek+i); for (;buf[i]&&iprintf ("%c", buf[i]); else p->printf ("."); } p->printf (" "); break; case 's': p->printf ("0x%08x = ", seek+i); memset (buffer, '\0', 255); if (p->iob.read_at) p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248); else { printf ("(cannot read memory)\n"); break; } p->printf ("0x%08x -> 0x%08x ", seek+i, addr); p->printf ("%s ", buffer); i+=4; break; default: /* ignore unknown chars */ break; } p->printf ("\n"); last = tmp; } if (otimes>1) p->printf ("}\n"); arg = orig; idx = 0; } // free((void *)&args); }