void search_similar_pattern(int count) { u8 *block = malloc (config.block_size); /* backup basic block */ radare_read(0); memcpy (block, config.block, config.block_size); radare_controlc (); radare_read (1); // read next block while (!config.interrupted && config.seek<config.size) { int diff = memcmpdiff(config.block, block, config.block_size); int equal = config.block_size-diff; // equal sera un numero petit quan diff sigui gran // quan equal sigui gran diff sera petit if (equal >= count) { //count > equal) { //if (count > equal) { cons_printf("0x%08llx %d/%d\n", config.seek, equal, config.block_size); cons_flush(); radare_read(1); } else { config.seek += 1; // skip diff bytes can be faster ?? //config.seek += diff; // skip diff bytes can be faster ?? int ret = radare_read(0); if (ret<config.block_size)break; } } radare_controlc_end (); free (block); }
// TODO: handle Control-C void radare_search_aes() { ut64 oseek = config.seek; ut64 limit = config.size; size_t bsize = config.block_size; int found = 0; int i; config.block_size = 512; if (config.limit) limit = config.limit; radare_controlc(); while(!config.interrupted && (( limit != -1 && config.seek < limit) || limit == -1)) { radare_read(0); for(i=0;i<256;i++) { if (aes_key_test(config.block+i)) { printf("%03d 0x%08x\n", found, (uint)config.seek+i); fflush(stdout); found++; } } radare_seek(config.seek + 256, SEEK_SET); } eprintf("%d AES keys found\n",found ); radare_controlc_end(); config.seek = oseek; config.block_size = bsize; }
int search_from_file(char *file) { int i, ret; ut64 tmp = config.seek; tokenizer *t; if (strchr(file, '?')) { printf("Usage: /. file\n"); printf("File format:\n"); printf(" token: keywordname\n"); printf(" string: keyword\n"); printf(" mask: binarymask\n"); return 0; } t = binparse_new_from_file(file); if (t == NULL) return 0; t->callback = &radare_tsearch_callback; nhit = 0; #if __UNIX__ D go_alarm(search_alarm); #endif radare_controlc(); // TODO: do it generic (as for init) radare_cmd("fs search", 0); for(radare_read(0);!config.interrupted&& config.seek < config.size;radare_read(1)) { for(i=0;i<config.block_size;i++) { ret = update_tlist(t, config.block[i], config.seek+i); if (ret == -1) break; } } radare_controlc_end(); #if __UNIX__ D go_alarm(SIG_IGN); #endif binparser_free(t); radare_seek(tmp, SEEK_SET); return 1; }
static int radare_tsearch_callback(struct _tokenizer *t, int i, ut64 where) { char flag_name[128]; ut64 off = config.seek; if (align != 0 && where%align != 0) return 1; if (search_count && nhit >= search_count) return 1; nhit++; radare_flag_name (flag_name, i, nhit); radare_seek(where, SEEK_SET); radare_read(0); if (search_flag) flag_set(flag_name, where, 0); if (search_cmdhit && search_cmdhit[0]!='\0') { char *cmdhit = strdup(search_cmdhit); radare_seek(where, SEEK_SET); setenv("KEYWORD", search_last_keyword, 1); // XXX this is not last-keyword!! must array this! radare_cmd(cmdhit, 0); free(cmdhit); radare_controlc(); } if (search_verbose) { u8 *ptr = config.block; //+(where-config.seek)-3; cons_printf("%03d 0x%08llx %s ", nhit, where, flag_name); for(i=0;i<20;i++) { if (is_printable(ptr[i])) cons_printf("%c", ptr[i]); } cons_printf("\n"); } //D { fprintf(stderr, "\r%d\n", nhit); fflush(stderr); } fflush(stdout); config.seek = off; return 0; }
int search_range(char *range) { int len, i,j; char str[128]; int num = -1, num2 = -1; tokenizer *t; ut64 tmp = config.seek; ut64 search_from; ut64 search_to; ut64 limit; int range_n = 0; int f0 = 0; ut64 s; if (range == NULL) return 0; free(search_last_keyword); search_last_keyword = strdup(range); // init stuff search_cmdhit = config_get("cmd.hit"); search_count = (int)(size_t)config_get_i("cfg.count"); search_flag = (int)(size_t)config_get("search.flag"); search_from = config_get_i("search.from"); search_to = config_get_i("search.to"); search_verbose = (int)(size_t)config_get("search.verbose"); if (config_get("search.inar")) { if (! ranges_get_n(range_n++, &search_from, &search_to)) { eprintf("No ranges defined\n"); return 0; } printf("Searching using ranges...\n"); } // twice hit_idx = 1; // reset hit index radare_cmd("f -hit0_*", 0); radare_cmd("f -hit0_*", 0); radare_cmd("fs search", 0); do { nhit = 0; t = binparse_new(0); align = config_get_i("search.align"); t->callback = &radare_tsearch_callback; len = strlen(range); // foreach token in range for(j=i=0;i<len;i++,j++) { str[j] = range[i]; str[j+1] = '\0'; switch(range[i+1]) { case '-': num = atoi(str); i++; j=-1; f0=1; break; case '\0': case ',': if (str[0]=='\0') break; num2 = atoi(str); if (f0) { f0=0; if (num == -1) { printf("syntax error\n"); break; } for(j = num;j<=num2;j++) binparse_add_search(t, j); } else binparse_add_search(t, num2); j=-1; str[0]='\0'; i++; break; } } #if __UNIX__ go_alarm(search_alarm); #endif /* search loop */ radare_controlc(); config.seek = search_from; limit = config.limit; if (search_to!=0) limit = search_to; //D eprintf("Searching from 0x%08llx to 0x%08llx\n", search_from, (search_to==0)?-1:search_to); for(i=1, radare_read(0); !config.interrupted; i = radare_read(1)) { s = config.seek; if (i==0) { //eprintf("read err at 0x%08llx\n", config.seek); break; } if (limit && config.seek >= limit) break; if (config.debug && config.seek == 0xFFFFFFFF) break; for(i=0;!config.interrupted && i<config.block_size;i++) { if (update_tlist(t, config.block[i], config.seek+i)) { config.seek = s; radare_read(0); } } config.seek = s; } } while(config_get("search.inar") && ranges_get_n(range_n++, &search_from, &search_to)); binparser_free(t); #if __UNIX__ go_alarm(SIG_IGN); #endif if (config.interrupted) { printf("\nStopped at 0x"OFF_FMTx" (flag search_stop)\n", config.seek); flag_set("search_stop",config.seek, 0); } radare_controlc_end(); radare_seek(tmp, SEEK_SET); if (!search_verbose) printf("\n"); return 1; }
int search_from_simple_file(char *file) { FILE *fd; char *ptr, buf[4096], cmd[4096]; //int i,ret; ut64 tmp = config.seek; //tokenizer *t; if (strchr(file, '?')) { cons_printf("Usage: /: file [file2] [file3] ...\n" "File format:\n" " puts 89823993982839\n" " scanf 89844483241839\n"); return 0; } fd = fopen(file, "r"); if (fd == NULL) { eprintf("Cannot open file '%s'\n", file); return 0; } config_set("cfg.verbose", "false"); while(!feof(fd) && !config.interrupted) { /* read line */ buf[0]='\0'; fgets(buf, 4095, fd); if (buf[0]=='\0') continue; buf[strlen(buf)-1]='\0'; ptr = strchr(buf, ' '); if (ptr) { ptr[0]='\0'; sprintf(cmd, "hit.%s_%%d%%d", buf); config_set("search.flagname", cmd); sprintf(cmd, ":/x %s", ptr+1); radare_cmd_raw(cmd, 0); //eprintf("(%s)(%s)\n", buf, ptr+1); } } config_set("cfg.verbose", "true"); config_set("search.flagname", "hit%d_%d"); fclose(fd); #if 0 t = binparse_new_from_simple_file(file); if (t == NULL) return 0; t->callback = &radare_tsearch_callback; nhit = 0; radare_controlc(); // TODO: do it generic (as for init) radare_cmd("fs search", 0); for(radare_read(0);!config.interrupted&& config.seek < config.size;radare_read(1)) { for(i=0;i<config.block_size;i++) { ret = update_tlist(t, config.block[i], config.seek+i); if (ret == -1) break; } } radare_controlc_end(); binparser_free(t); #endif radare_seek(tmp, SEEK_SET); radare_read(0); return 1; }
/* TODO: needs refactoring */ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, int len, const char *fmt, int elem, const char *setval) { int nargs, i, j, nexti, idx, times, otimes, endian, isptr = 0; int (*realprintf)(const char *str, ...); int (*oldprintf)(const char *str, ...); const char *argend = fmt+strlen (fmt); ut64 addr = 0, addr64 = 0, seeki = 0;; char *args = NULL, *bracket, tmp, last = 0; const char *arg = fmt; int viewflags = 0; char namefmt[8]; ut8 *buf, buffer[256]; nexti = nargs = endian = i = j = 0; if (len<1) return 0; buf = malloc (len); if (!buf) return 0; memcpy (buf, b, len); endian = p->big_endian; oldprintf = NULL; realprintf = p->printf; while (*arg && iswhitechar (*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"); goto beach; } *end='\0'; times = r_num_math (NULL, bracket+1); arg = end + 1; } if (*arg=='\0') { print_format_help (p); goto beach; } /* 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; i<nargs; i++) { int len = strlen (r_str_word_get0 (args+1, i)); if (len>maxl) maxl = len; } l++; snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl); } /* go format */ i = 0; if (!times) 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); idx = 0; arg = orig; for (idx=0; i<len && arg<argend && *arg; idx++, arg++) { seeki = seek+i; addr = 0LL; 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: switch (isptr) { case 1: nexti = i + (p->bits/8); i = 0; tmp = *arg; memset (buf, '\0', len); p->printf ("(*0x%"PFMT64x") ", addr); if (p->iob.read_at) { p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4); } else { eprintf ("(cannot read memory)\n"); break; } isptr = 2; break; case 2: // restore state after pointer seek i = nexti; seeki = seek+i; memcpy (buf, b, len); isptr = 0; arg--; idx--; continue; } if (tmp == 0 && last != '*') break; /* skip chars */ switch (tmp) { case '*': isptr = 1; if (i<=0 || !arg[1]) break; arg++; tmp = *arg; //last; // arg--; // idx--; goto feed_me_again; case '+': idx--; viewflags = !viewflags; continue; case 'e': // tmp swap endian idx--; endian ^= 1; continue; case ':': // skip char i+=4; idx-=4; continue; case '.': // skip char i++; idx--; continue; case 'p': tmp = (p->bits==64)?'q': 'x'; //tmp = (sizeof (void*)==8)? 'q': 'x'; break; case '?': // help print_format_help (p); idx--; i = len; // exit continue; } if (otimes>1) p->printf (" "); #define MUSTSET (setval && elem == idx) #define MUSTSEE (elem == -1 || elem == idx) if (MUSTSEE) { if (!(MUSTSET)) { if (oldprintf) p->printf = oldprintf; if (idx<nargs) p->printf (namefmt, r_str_word_get0 (args, idx)); } } else { if (!oldprintf) oldprintf = p->printf; p->printf = nullprintf; } /* 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': if (MUSTSET) { realprintf ("?e pf e not yet supported\n"); } else { double doub; memcpy (&doub, buf+i, sizeof (double)); p->printf ("0x%08"PFMT64x" = (double) ", seeki); p->printf ("%e", doub); i += 8; } break; case 'q': if (MUSTSET) { realprintf ("wv8 %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); p->printf ("(qword) "); p->printf ("0x%08"PFMT64x" ", addr64); } i += 8; break; case 'b': if (MUSTSET) { realprintf ("w %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); p->printf ("%d ; 0x%02x ; '%c' ", buf[i], buf[i], IS_PRINTABLE (buf[i])?buf[i]:0); } i++; break; case 'c': if (MUSTSET) { realprintf ("?e pf c not yet implemented\n"); } else { p->printf ("0x%08"PFMT64x" = ", seeki); p->printf ("%d ; %d ; '%c' ", buf[i], (char)buf[i], IS_PRINTABLE (buf[i])?buf[i]:0); } i++; break; case 'B': if (MUSTSET) { realprintf ("?e pf B not yet implemented\n"); } else { 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%08"PFMT64x" = ", seeki); 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 'f': if (MUSTSET) { realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = %f", seeki, (float)(addr)); } i += 4; break; case 'i': case 'd': // TODO: support unsigned int? if (MUSTSET) { realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); p->printf ("%"PFMT64d" ", addr); } i += 4; break; case 'D': if (p->disasm && p->user) i += p->disasm (p->user, seeki); break; case 'x': if (MUSTSET) { realprintf ("wv4 %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { ut32 addr32 = (ut32)addr; p->printf ("0x%08"PFMT64x" = ", seeki); 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) if (MUSTSET) { realprintf ("wv2 %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08x = ", seeki); if (endian) addr = (*(buf+i))<<8 | (*(buf+i+1)); else addr = (*(buf+i+1))<<8 | (*(buf+i)); p->printf ("0x%04x ", addr); } i+=2; break; case 'z': // zero terminated string if (MUSTSET) { realprintf ("?e pf z not yet supported\n"); } else { p->printf ("0x%08"PFMT64x" = ", seeki); for (; buf[i]&&i<len; i++) { if (IS_PRINTABLE (buf[i])) p->printf ("%c", buf[i]); else p->printf ("."); } } break; case 'Z': // zero terminated wide string p->printf ("0x%08"PFMT64x" = ", seeki); for (; buf[i] && i<len; i+=2) { if (IS_PRINTABLE (buf[i])) p->printf ("%c", buf[i]); else p->printf ("."); } p->printf (" "); break; case 's': p->printf ("0x%08"PFMT64x" = ", seeki); memset (buffer, '\0', 255); if (p->iob.read_at) { p->iob.read_at (p->iob.io, (ut64)addr, buffer, sizeof (buffer)-8); } else { printf ("(cannot read memory)\n"); break; } p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ", seeki, addr); p->printf ("%s ", buffer); i += 4; break; case 'S': p->printf ("0x%08"PFMT64x" = ", seeki); memset (buffer, '\0', 255); if (p->iob.read_at) { p->iob.read_at (p->iob.io, addr64, buffer, sizeof (buffer)-8); } else { printf ("(cannot read memory)\n"); break; } p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ", seeki, addr); p->printf ("%s ", buffer); i += 8; break; default: /* ignore unknown chars */ break; } if (viewflags && p->offname) { const char *s = p->offname (p->user, seeki); if (s) p->printf ("@(%s)", s); s = p->offname (p->user, addr); if (s) p->printf ("*(%s)", s); } if (tmp != 'D') p->printf ("\n"); last = tmp; } if (otimes>1) p->printf ("}\n"); arg = orig; idx = 0; } if (oldprintf) p->printf = oldprintf; beach: free (buf); if (args) { free (args); } return i; }
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len, const char *fmt, int elem, const char *setval) { int nargs, i, j, invalid, nexti, idx, times, otimes, endian, isptr = 0; int (*oldprintf)(const char *str, ...); const char *argend = fmt+strlen (fmt); ut64 addr = 0, addr64 = 0, seeki = 0;; char *args = NULL, *bracket, tmp, last = 0; const char *arg = fmt; int viewflags = 0, flag = (elem==SEEFLAG)?1:0; char namefmt[8]; static int slide=0; ut8 *buf; nexti = nargs = i = j = 0; if (len < 1) return 0; buf = malloc (len); if (!buf) return 0; memcpy (buf, b, len); endian = p->big_endian; oldprintf = NULL; realprintf = p->printf; while (*arg && iswhitechar (*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"); goto beach; } *end='\0'; times = r_num_math (NULL, bracket+1); arg = end + 1; } if (*arg=='\0' || *arg=='?') { print_format_help (p); goto beach; } /* get args */ args = strchr (arg, ' '); if (args) { int l=0, maxl = 0; argend = args; args = strdup (args+1); nargs = r_str_word_set0 (args); if (nargs == 0) R_FREE (args); for (i=0; i<nargs; i++) { const int len = strlen (r_str_word_get0 (args, i)); if (len > maxl) maxl = len; } l++; snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl+6*slide%STRUCTPTR); } /* go format */ i = 0; if (!times) 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); arg = orig; for (idx=0; i<len && arg<argend && *arg; arg++) { int size; char *name = NULL; seeki = seek+i; addr = 0LL; invalid = 0; if (arg[0] == '[') { char *end = strchr (arg,']'); if (end == NULL) { eprintf ("No end bracket.\n"); goto beach; } *end = '\0'; size = r_num_math (NULL, arg+1); arg = end + 1; *end = ']'; } else { size = -1; } updateAddr (buf, i, endian, &addr, &addr64); tmp = *arg; if (otimes>1) p->printf (" "); #define MUSTSET (setval && elem == idx) #define MUSTSEE (elem == -1 || elem == idx) if (MUSTSEE && !flag) { if (!(MUSTSET)) { if (oldprintf) p->printf = oldprintf; if (idx<nargs && tmp != 'e' && isptr == 0) { p->printf (namefmt, r_str_word_get0 (args, idx)); idx++; } } } else { if (!oldprintf) oldprintf = p->printf; p->printf = nullprintf; } feed_me_again: switch (isptr) { case 1: { nexti = i + (p->bits/8); i = 0; if(tmp == '?' )seeki = addr; memset (buf, '\0', len); p->printf ("(*0x%"PFMT64x") ", addr); if (addr == 0) isptr = NULLPTR; else isptr = PTRBACK; if (/*addr<(b+len) && addr>=b && */p->iob.read_at) { /* The test was here to avoid segfault in the next line, but len make it doesnt work... */ p->iob.read_at (p->iob.io, (ut64)addr, buf, len-4); updateAddr (buf, i, endian, &addr, &addr64); } else { eprintf ("(SEGFAULT: cannot read memory at 0x%08"PFMT64x", Block: %s, blocksize: 0x%x)\n", addr, b, len); p->printf("\n"); goto beach; } } break; case 2: // restore state after pointer seek i = nexti; seeki = seek+i; memcpy (buf, b, len); isptr = NOPTR; arg--; continue; } if (tmp == 0 && last != '*') break; /* skip chars */ switch (tmp) { case '*': // next char is a pointer isptr = PTRSEEK; arg++; tmp = *arg; //last; goto feed_me_again; case '+': // toggle view flags viewflags = !viewflags; continue; case 'e': // tmp swap endian endian ^= 1; continue; case ':': // skip 4 bytes if (size == -1) i+=4; else while (size--) i+=4; continue; case '.': // skip 1 byte if (size == -1) i++; else while (size--) i++; continue; case 'p': // pointer reference tmp = (p->bits == 64)? 'q': 'x'; //tmp = (sizeof (void*)==8)? 'q': 'x'; break; } if (flag && isptr != NULLPTR) { if (tmp == '?') { char *n = strdup (r_str_word_get0 (args, idx)+1); char *par = strchr (n, ')'); if (par == NULL) { eprintf ("No end parenthesis for struct name"); free (n); goto beach; } else { *par = '.'; } realprintf ("f %s_", n); free(n); } else if (slide>0 && idx==0) { realprintf ("%s=0x%08"PFMT64x"\n", r_str_word_get0 (args, idx), seeki); } else realprintf ("f %s=0x%08"PFMT64x"\n", r_str_word_get0 (args, idx) , seeki); idx++; } if (isptr == NULLPTR) { p->printf ("NULL"); isptr = PTRBACK; } else /* cmt chars */ switch (tmp) { #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': //WTF is this? 'e' is supposed to swap endians?! if (size > 0) p->printf ("Size not yet implemented\n"); if (MUSTSET) { realprintf ("?e pf e not yet supported\n"); } else { double doub; memcpy (&doub, buf+i, sizeof (double)); p->printf ("0x%08"PFMT64x" = (double) ", seeki); p->printf ("%e", doub); i += 8; } break; case 'q': r_print_format_quadword(p, endian, MUSTSET, setval, seeki, buf, i, size); i += (size==-1) ? 8 : 8*size; break; case 'b': r_print_format_byte(p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 1 : size; break; case 'c': r_print_format_char (p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 1 : size; break; case 'X': size = r_print_format_hexpairs (p, endian, MUSTSET, setval, seeki, buf, size); i += size; break; case 'T': if(r_print_format_10bytes(p, MUSTSET, setval, seeki, addr, buf) == 0) i += (size==-1) ? 4 : 4*size; break; case 'f': r_print_format_float(p, endian, MUSTSET, setval, seeki, buf, i, size); i += (size==-1) ? 4 : 4*size; break; case 'i': case 'd': r_print_format_hex(p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 4 : 4*size; break; case 'D': if (size>0) p->printf ("Size not yet implemented\n"); if (p->disasm && p->user) i += p->disasm (p->user, seeki); break; case 'o': r_print_format_octal (p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 4 : 4*size; break; case 'x': r_print_format_hexflag(p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 4 : 4*size; break; case 'w': case '1': // word (16 bits) r_print_format_word(p, endian, MUSTSET, setval, seeki, buf, i, size); i+= (size==-1) ? 2 : 2*size; break; case 'z': // zero terminated string if (MUSTSET) { int buflen = strlen ((const char *)buf); if (buflen>seeki) { buflen = strlen ((const char *)buf+seeki); } if (strlen (setval) > buflen) { eprintf ("Warning: new string is longer than previous one \n"); } realprintf ("w %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); for (; ((size || size==-1) && buf[i]) && i<len; i++) { if (IS_PRINTABLE (buf[i])) p->printf ("%c", buf[i]); else p->printf ("."); size -= (size==-1) ? 0 : 1; } } if (size == -1) i++; else while (size--) i++; break; case 'Z': // zero terminated wide string if (MUSTSET) { if ((size = strlen(setval)) > r_wstr_clen((char*)(buf+seeki))) eprintf ("Warning: new string is longer than previous one\n"); realprintf ("ww %s @ 0x%08"PFMT64x"\n", setval, seeki); } else { p->printf ("0x%08"PFMT64x" = ", seeki); for (; ((size || size==-1) && buf[i]) && i<len; i+=2) { if (IS_PRINTABLE (buf[i])) p->printf ("%c", buf[i]); else p->printf ("."); size -= (size==-1) ? 0 : 1; } } if (size == -1) i+=2; else while (size--) i+=2; break; case 's': if (r_print_format_ptrstring (p, seeki, addr64, addr, 0) == 0) i += (size==-1) ? 4 : 4*size; break; case 'S': if (r_print_format_ptrstring (p, seeki, addr64, addr, 1) == 0) i += (size==-1) ? 8 : 8*size; break; case 'B': // resolve bitfield { char *structname, *osn; char *bitfield = NULL; structname = osn = strdup (r_str_word_get0 (args, idx-1)); switch (size) { case 1: addr &= UT8_MAX; break; case 2: addr &= UT16_MAX; break; case 4: addr &= UT32_MAX; break; } if (*structname == '(') { name = strchr (structname, ')'); } else { eprintf ("Bitfield name missing (%s)\n", structname); free (structname); goto beach; } structname++; if (name) *(name++) = '\0'; else eprintf ("No ')'\n"); if (p->get_bitfield) bitfield = p->get_bitfield (p->user, structname, addr); if (bitfield && *bitfield) { p->printf (" %s (bitfield) = %s\n", name, bitfield); } else { p->printf (" %s (bitfield) = `tb %s 0x%x`\n", name, structname, addr); } i+= 4; //(isptr) ? 4 : s; free (osn); free (bitfield); } break; case 'E': // resolve enum { char *enumname, *osn; char *enumvalue = NULL; enumname = osn = strdup (r_str_word_get0 (args, idx-1)); switch (size) { case 1: addr &= UT8_MAX; break; case 2: addr &= UT16_MAX; break; case 4: addr &= UT32_MAX; break; } if (*enumname == '(') { name = strchr (enumname, ')'); } else { eprintf ("Enum name missing (%s)\n", enumname); free (enumname); goto beach; } enumname++; if (name) *(name++) = '\0'; else eprintf ("No ')'\n"); if (p->get_enumname) enumvalue = p->get_enumname (p->user, enumname, addr); if (enumvalue && *enumvalue) { p->printf (" %s (enum) = 0x%"PFMT64x" ; %s\n", name, addr, enumvalue); } else { p->printf (" %s (enum) = `te %s 0x%x`\n", name, enumname, addr); } i+= (size==-1) ? 1 : size; free (osn); free (enumvalue); } break; case '?': { int s; char *structname, *osn; structname = osn = strdup (r_str_word_get0 (args, idx-1)); if (*structname == '(') { name = strchr (structname, ')'); } else { eprintf ("Struct name missing (%s)\n", structname); free (structname); goto beach; } structname++; if (name) *(name++) = '\0'; else eprintf ("No ')'\n"); p->printf ("<struct>\n"); if (flag) slide+=STRUCTFLAG; slide += (isptr) ? STRUCTPTR : NESTEDSTRUCT; s = r_print_format_struct (p, seeki, buf+i, len, structname--, slide); i+= (isptr) ? 4 : s; slide -= (isptr) ? STRUCTPTR : NESTEDSTRUCT; if (flag) slide-=STRUCTFLAG; free (osn); break; } default: /* ignore unknown chars */ invalid = 1; break; } if (!flag && (!MUSTSEE || MUSTSET)) idx++; if (viewflags && p->offname) { const char *s = p->offname (p->user, seeki); if (s) p->printf ("@(%s)", s); s = p->offname (p->user, addr); if (s) p->printf ("*(%s)", s); } if (tmp != 'D' && !invalid && name==NULL) p->printf ("\n"); last = tmp; } if (otimes>1) p->printf ("}\n"); arg = orig; } if (oldprintf) p->printf = oldprintf; beach: free (buf); if (args) free (args); return i; }