/* radare - LGPL - Copyright 2009-2012 // pancake */ static int printzoomcallback(void *user, int mode, ut64 addr, ut8 *bufz, ut64 size) { RCore *core = (RCore *) user; int j, ret = 0; RListIter *iter; RFlagItem *flag; switch (mode) { case 'p': for (j=0; jflags->flags, iter, flag) if (flag->offset <= addr && addr < flag->offset+flag->size) ret++; break; case 's': j = r_flag_space_get (core->flags, "strings"); r_list_foreach (core->flags->flags, iter, flag) { if (flag->space == j && ((addr <= flag->offset && flag->offset < addr+size) || (addr <= flag->offset+flag->size && flag->offset+flag->size < addr+size))) ret++; } break; case '0': // 0xFF for (j=0; jblocksize; ut32 tbs = core->blocksize; /* TODO: Change also blocksize for 'pd'.. */ l = len; if (input[0] && input[1]) { if (input[2]) { l = (int) r_num_math (core->num, input+(input[1]==' '?2:3)); /* except disasm and memoryfmt (pd, pm) */ if (input[0] != 'd' && input[0] != 'm') { if (l>0) len = l; if (l>tbs) r_core_block_size (core, l); l = len; } }// else l = 0; } else l = len; i = r_config_get_i (core->config, "io.maxblk"); if (i && l > i) { eprintf ("This block size is too big. Did you mean 'p%c @ %s' instead?\n", *input, input+2); return R_FALSE; } if (input[0] && input[1] == 'f') { RAnalFcn *f = r_anal_fcn_find (core->anal, core->offset, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); if (f) len = f->size; else eprintf ("Cannot find function at 0x%08"PFMT64x"\n", core->offset); } core->num->value = len; switch (*input) { case '%': { ut64 off = core->io->off; ut64 s = core->file?core->file->size:0; ut64 piece = 0; int w = core->print->cols * 4; piece = s/w; r_cons_strcat (" ["); for (i=0; i=from && offfile->filename); if (out) { r_cons_strcat (out); free (out); } } break; case 'b': { const int size = len*8; char *buf = malloc (size+1); if (buf) { r_str_bits (buf, core->block, size, NULL); r_cons_printf ("%s\n", buf); free (buf); } 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 'i': { RAsmOp asmop; int j, ret, err = 0; const ut8 *buf = core->block; int tbs = 0; int bs = core->blocksize; if (input[1]=='f') { RAnalFcn *f = r_anal_fcn_find (core->anal, core->offset, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); if (f) { len = bs = f->size; tbs = core->blocksize; } } if (bs>core->blocksize) r_core_block_size (core, tbs); if (l==0) l = len; for (i=j=0; iassembler, &asmop, buf+i, core->blocksize-i); if (ret<1) { ret = err = 1; r_cons_printf ("???\n"); } else r_cons_printf ("%s\n", asmop.buf_asm); } if (tbs) r_core_block_size (core, tbs); return err; } case 'D': case 'd': switch (input[1]) { case 'i': {// TODO RAsmOp asmop; int j, ret, err = 0; const ut8 *buf = core->block; if (l==0) l = len; for (i=j=0; iblocksize && jassembler, &asmop, buf+i, core->blocksize-i); if (ret<1) { ret = err = 1; r_cons_printf ("0x%08"PFMT64x" %14s%02x %s\n", core->offset+i, "", buf[i], "???"); } else r_cons_printf ("0x%08"PFMT64x" %16s %s\n", core->offset+i, asmop.buf_hex, asmop.buf_asm); } return err; } break; case 'a': { RAsmOp asmop; int j, ret, err = 0; const ut8 *buf = core->block; if (l==0) l = len; for (i=j=0; iblocksize && jassembler, &asmop, buf+i, core->blocksize-i); if (ret<1) { ret = err = 1; r_cons_printf ("???\n"); } else r_cons_printf ("0x%08"PFMT64x" %16s %s\n", core->offset+i, asmop.buf_hex, asmop.buf_asm); } return R_TRUE; } break; case 'b': { RAnalBlock *b = r_anal_bb_from_offset (core->anal, core->offset); if (b) { ut8 *block = malloc (b->size+1); if (block) { r_core_read_at (core, b->addr, block, b->size); core->num->value = r_core_print_disasm (core->print, core, b->addr, block, b->size, 9999, 0); free (block); return 0; } } else eprintf ("Cannot find function at 0x%08"PFMT64x"\n", core->offset); } break; break; case 'f': { RAnalFcn *f = r_anal_fcn_find (core->anal, core->offset, R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); if (f) { ut8 *block = malloc (f->size+1); if (block) { r_core_read_at (core, f->addr, block, f->size); core->num->value = r_core_print_disasm (core->print, core, f->addr, block, f->size, 9999, 0); free (block); return 0; } } else eprintf ("Cannot find function at 0x%08"PFMT64x"\n", core->offset); } break; case 'l': { RAsmOp asmop; int j, ret; const ut8 *buf = core->block; if (l==0) l= len; for (i=j=0; iblocksize && jassembler, &asmop, buf+i, len-i); printf ("%d\n", ret); if (ret<1) ret = 1; } return 0; } break; case '?': eprintf ("Usage: pd[f|i|l] [len] @ [addr]\n"); //TODO: eprintf (" pdr : disassemble resume\n"); eprintf (" pda : disassemble all possible opcodes (byte per byte)\n"); eprintf (" pdb : disassemble basic block\n"); eprintf (" pdf : disassemble function\n"); eprintf (" pdi : like 'pi', with offset and bytes\n"); eprintf (" pdl : show instruction sizes\n"); return 0; break; } //if (core->visual) // l = core->cons->rows-core->cons->lines; if (l<0) { RList *bwdhits; RListIter *iter; RCoreAsmHit *hit; ut8 *block = malloc (core->blocksize); if (block) { l = -l; bwdhits = r_core_asm_bwdisassemble (core, core->offset, l, core->blocksize); if (bwdhits) { r_list_foreach (bwdhits, iter, hit) { r_core_read_at (core, hit->addr, block, core->blocksize); core->num->value = r_core_print_disasm (core->print, core, hit->addr, block, core->blocksize, l, 1); r_cons_printf ("------\n"); } r_list_free (bwdhits); } free (block); } } else { core->num->value = r_core_print_disasm ( core->print, core, core->offset, core->block, len, l, (*input=='d')); } break; case 's': if (input[1]=='p') { int mylen = core->block[0]; // TODO: add support for 2-4 byte length pascal strings r_print_string (core->print, core->offset, core->block, mylen, 0, 1, 0); //, 78, 1); core->num->value = mylen; } else if (input[1]==' ') { len = r_num_math (core->num, input+2); r_print_string (core->print, core->offset, core->block, len, 0, 0, 0); //, 78, 1); } else r_print_string (core->print, core->offset, core->block, len, 0, 1, 0); //, 78, 1); break; case 'S': r_print_string (core->print, core->offset, core->block, len, 1, 1, 0); //, 78, 1); break; case 'm': if (input[1]=='?') { r_cons_printf ("Usage: pm [file|directory]\n" " r_magic will use given file/dir as reference\n" " output of those magic can contain expressions like:\n" " foo@0x40 # use 'foo' magic file on address 0x40\n" " @0x40 # use current magic file on address 0x40\n" " \\n # append newline\n" " e dir.magic # defaults to "R_MAGIC_PATH"\n" ); } else r_core_magic (core, input+1, R_TRUE); break; case 'u': r_print_string (core->print, core->offset, core->block, len, 0, 1, 1); //, 78, 1); break; case 'U': r_print_string (core->print, core->offset, core->block, len, 1, 1, 1); //, 78, 1); break; case 'c': r_print_code (core->print, core->offset, core->block, len); //, 78, 1); break; case 'r': r_print_raw (core->print, core->block, len); break; case 'o': r_print_hexdump (core->print, core->offset, core->block, len, 8, 1); //, 78, !(input[1]=='-')); break; case 'x': r_print_hexdump (core->print, core->offset, core->block, len, 16, 1); //, 78, !(input[1]=='-')); break; case '6': { int malen = (core->blocksize*4)+1; ut8 *buf = malloc (malen); memset (buf, 0, malen); switch (input[1]) { case 'e': r_base64_encode (buf, core->block, core->blocksize); printf ("%s\n", buf); break; case 'd': if (r_base64_decode (buf, core->block, core->blocksize)) printf ("%s\n", buf); else eprintf ("r_base64_decode: invalid stream\n"); break; default: eprintf ("Usage: p6[ed] [len] ; base 64 encode/decode\n"); break; } free (buf); } break; case '8': r_print_bytes (core->print, core->block, len, "%02x"); break; case 'f': r_print_format (core->print, core->offset, core->block, len, input+1); break; case 'n': // easter penis for (l=0; l<10; l++) { printf ("\r8"); for (len=0;lenprint, core->block+l, sizeof (time_t)); break; case 'd': for (l=0; lprint, core->block+l, 4); break; case 'n': core->print->bigendian = !core->print->bigendian; for (l=0; lprint, core->block+l, sizeof (ut64)); core->print->bigendian = !core->print->bigendian; break; case '?': r_cons_printf ( "Usage: pt[dn?]\n" " pt print unix time (32 bit cfg.bigendian)\n" " ptd print dos time (32 bit cfg.bigendian)\n" " ptn print ntfs time (64 bit !cfg.bigendian)\n" " pt? show help message\n"); break; } break; case 'Z': if (input[1]=='?') { r_cons_printf ( "Usage: pZ [len]\n" " print N bytes where each byte represents a block of filesize/N\n" "Configuration:\n" " zoom.maxsz : max size of block\n" " zoom.from : start address\n" " zoom.to : end address\n" " zoom.byte : specify how to calculate each byte\n" " p : number of printable chars\n" " f : count of flags in block\n" " s : strings in range\n" " 0 : number of bytes with value '0'\n" " F : number of bytes with value 0xFF\n" " e : calculate entropy and expand to 0-255 range\n" " h : head (first byte value)\n" "WARNING: On big files, use 'zoom.byte=h' or restrict ranges\n"); } else { char *oldzoom = NULL; ut64 maxsize = r_config_get_i (core->config, "zoom.maxsz"); ut64 from, to; int oldva = core->io->va; from = 0; core->io->va = 0; to = r_io_size (core->io); from = r_config_get_i (core->config, "zoom.from"); to = r_config_get_i (core->config, "zoom.to"); if (input[1] != '\0' && input[1] != ' ') { oldzoom = strdup (r_config_get (core->config, "zoom.byte")); if (!r_config_set (core->config, "zoom.byte", input+1)) { eprintf ("Invalid zoom.byte mode (%s)\n", input+1); free (oldzoom); return R_FALSE; } } r_print_zoom (core->print, core, printzoomcallback, from, to, core->blocksize, (int)maxsize); if (oldzoom) { r_config_set (core->config, "zoom.byte", oldzoom); free (oldzoom); } if (oldva) core->io->va = oldva; } break; default: r_cons_printf ( "Usage: p[fmt] [len]\n" " p= show entropy bars of full file\n" " p6[de] [len] base64 decode/encode\n" " p8 [len] 8bit hexpair list of bytes\n" " pb [len] bitstream of N bytes\n" " pi[f] [len] show opcodes of N bytes\n" " pd[lf] [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" " pm [magic] print libmagic data (pm? for more information)\n" " ps [len] print string\n" " psp print pascal string\n" " pS [len] print wide string\n" " pt [len] print different timestamps\n" " pr [len] print N raw bytes\n" " pu [len] print N url encoded bytes\n" " pU [len] print N wide url encoded bytes\n" " px [len] hexdump of N bytes\n" " pZ [len] print zoom view (see pZ? for help)\n"); break; } if (tbs != core->blocksize) r_core_block_size (core, tbs); return 0; } static int cmd_hexdump(void *data, const char *input) { return cmd_print (data, input-1); }