R_API void r_cons_flush() { const char *tee = I.teefile; if (I.noflush) return; if (I.null) { r_cons_reset (); return; } r_cons_filter (); if (I.is_interactive) { /* Use a pager if the output doesn't fit on the terminal window. */ if (I.pager && *I.pager && I.buffer_len > 0 && r_str_char_count (I.buffer, '\n') >= I.rows) { I.buffer[I.buffer_len-1] = 0; r_sys_cmd_str_full (I.pager, I.buffer, NULL, NULL, NULL); r_cons_reset (); } else if (I.buffer_len > CONS_MAX_USER) { #define COUNT_LINES 1 #if COUNT_LINES int i, lines = 0; for (i=0; I.buffer[i]; i++) { if (I.buffer[i]=='\n') lines ++; } if (lines>0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) { r_cons_reset (); return; } #else char buf[64]; char *buflen = r_num_units (buf, I.buffer_len); if (buflen && !r_cons_yesno ('n',"Do you want to print %s chars? (y/N)", buflen)) { r_cons_reset (); return; } #endif // fix | more | less problem r_cons_set_raw (1); } } if (tee && *tee) { FILE *d = r_sandbox_fopen (tee, "a+"); if (d != NULL) { if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) eprintf ("r_cons_flush: fwrite: error (%s)\n", tee); fclose (d); } else eprintf ("Cannot write on '%s'\n", tee); } r_cons_highlight (I.highlight); // is_html must be a filter, not a write endpoint if (I.is_html) r_cons_html_print (I.buffer); else r_cons_write (I.buffer, I.buffer_len); r_cons_reset (); if (I.newline) { eprintf ("\n"); I.newline = false; } }
/* Write a single memory map line to the console */ static void print_debug_map_line(RDebug *dbg, RDebugMap *map, ut64 addr, const char *input) { if (input[0] == 'q') { // "dmq" char buf[128]; char *name = (map->name && *map->name) ? r_str_newf ("%s.%s", map->name, r_str_rwx_i (map->perm)) : r_str_newf ("%08"PFMT64x".%s", map->addr, r_str_rwx_i (map->perm)); r_name_filter (name, 0); dbg->cb_printf ("0x%016"PFMT64x" - 0x%016"PFMT64x" %6s %5s %s\n", map->addr, map->addr_end, r_num_units (buf, map->addr_end - map->addr), r_str_rwx_i (map->perm), name); free (name); } else { char sizebuf[128]; const char *fmtstr = dbg->bits & R_SYS_BITS_64 ? "0x%016"PFMT64x" - 0x%016"PFMT64x" %c %s %6s %c %s %s %s%s%s\n" : "0x%08"PFMT64x" - 0x%08"PFMT64x" %c %s %6s %c %s %s %s%s%s\n"; const char *type = map->shared? "sys": "usr"; const char *flagname = dbg->corebind.getName ? dbg->corebind.getName (dbg->corebind.core, map->addr) : NULL; if (!flagname) { flagname = ""; } else if (map->name) { char *filtered_name = strdup (map->name); r_name_filter (filtered_name, 0); if (!strncmp (flagname, "map.", 4) && \ !strcmp (flagname + 4, filtered_name)) { flagname = ""; } free (filtered_name); } dbg->cb_printf (fmtstr, map->addr, map->addr_end, (addr>=map->addr && addr<map->addr_end)?'*':'-', type, r_num_units (sizebuf, map->size), map->user?'u':'s', r_str_rwx_i (map->perm), map->name?map->name:"?", map->file?map->file:"?", *flagname? " ; ": "", flagname); } }
R_API void r_cons_flush() { const char *tee = I.teefile; if (I.noflush) return; if (I.null) { r_cons_reset (); return; } r_cons_filter (); if (I.is_interactive) { /* Use a pager if the output doesn't fit on the terminal window. */ if (I.pager && *(I.pager) && I.buffer_len > 0 && r_str_char_count (I.buffer, '\n') >= I.rows) { I.buffer[I.buffer_len-1] = 0; r_sys_cmd_str_full (I.pager, I.buffer, NULL, NULL, NULL); r_cons_reset (); } else if (I.buffer_len > CONS_MAX_USER) { char buf[64]; char *buflen = r_num_units (buf, I.buffer_len); if (!r_cons_yesno ('n',"Do you want to print %s chars? (y/N)", buflen)) { r_cons_reset (); return; } } } if (tee&&*tee) { FILE *d = r_sandbox_fopen (tee, "a+"); if (d != NULL) { if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) eprintf ("r_cons_flush: fwrite: error (%s)\n", tee); fclose (d); } else eprintf ("Cannot write on '%s'\n", tee); } // is_html must be a filter, not a write endpoint if (I.is_html) r_cons_html_print (I.buffer); else r_cons_write (I.buffer, I.buffer_len); r_cons_reset (); }
static void print_debug_maps_ascii_art(RDebug *dbg, RList *maps, ut64 addr, int colors) { ut64 mul; // The amount of address space a single console column will represent in bar graph ut64 min = -1, max = 0; int width = r_cons_get_size (NULL) - 90; RListIter *iter; RDebugMap *map; if (width < 1) { width = 30; } r_list_sort (maps, cmp); mul = findMinMax (maps, &min, &max, 0, width); ut64 last = min; if (min != -1 && mul != 0) { const char *color_prefix = ""; // Color escape code prefixed to string (address coloring) const char *color_suffix = ""; // Color escape code appended to end of string const char *fmtstr; char size_buf[56]; // Holds the human formatted size string [124K] int skip = 0; // Number of maps to skip when re-calculating the minmax r_list_foreach (maps, iter, map) { r_num_units (size_buf, map->size); // Convert map size to human readable string if (colors) { color_suffix = Color_RESET; if (map->perm & 2) { // Writable maps are red color_prefix = Color_RED; } else if (map->perm & 1) { // Executable maps are green color_prefix = Color_GREEN; } else { color_prefix = ""; color_suffix = ""; } } else { color_prefix = ""; color_suffix = ""; } if ((map->addr - last) > UT32_MAX) { // TODO: Comment what this is for mul = findMinMax (maps, &min, &max, skip, width); // Recalculate minmax } skip++; fmtstr = dbg->bits & R_SYS_BITS_64 ? // Prefix formatting string (before bar) "map %4.8s %c %s0x%016"PFMT64x"%s |" : "map %4.8s %c %s0x%08"PFMT64x"%s |"; dbg->cb_printf (fmtstr, size_buf, (addr >= map->addr && \ addr < map->addr_end) ? '*' : '-', color_prefix, map->addr, color_suffix); // * indicates map is within our current seeked offset int col; for (col = 0; col < width; col++) { // Iterate over the available width/columns for bar graph ut64 pos = min + (col * mul); // Current address space to check ut64 npos = min + ((col + 1) * mul); // Next address space to check if (map->addr < npos && map->addr_end > pos) { dbg->cb_printf ("#"); // TODO: Comment what a # represents } else { dbg->cb_printf ("-"); } } fmtstr = dbg->bits & R_SYS_BITS_64 ? // Suffix formatting string (after bar) "| %s0x%016"PFMT64x"%s %s %s\n" : "| %s0x%08"PFMT64x"%s %s %s\n"; dbg->cb_printf (fmtstr, color_prefix, map->addr_end, color_suffix, r_str_rwx_i (map->perm), map->name); last = map->addr; } }
R_API bool r_diff_buffers_distance_original(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity) { int i, j, tmin, **m; ut64 totalsz = 0; if (!a || !b || la < 1 || lb < 1) return false; if (la == lb && !memcmp (a, b, la)) { if (distance != NULL) *distance = 0; if (similarity != NULL) *similarity = 1.0; return true; } totalsz = sizeof(int*) * (lb+1); for(i = 0; i <= la; i++) { totalsz += ((lb+1) * sizeof(int)); } if (totalsz >= 1024 * 1024 * 1024) { // 1 GB of ram char *szstr = r_num_units (NULL, totalsz); eprintf ("Too much memory required (%s) to run distance diff, Use -c.\n", szstr); free (szstr); return false; } if ((m = malloc ((la+1) * sizeof(int*))) == NULL) return false; for(i = 0; i <= la; i++) { if ((m[i] = malloc ((lb+1) * sizeof(int))) == NULL) { eprintf ("Allocation failed\n"); while (i--) free (m[i]); free (m); return false; } } for (i = 0; i <= la; i++) m[i][0] = i; for (j = 0; j <= lb; j++) m[0][j] = j; for (i = 1; i <= la; i++) { for (j = 1; j <= lb; j++) { int cost = (a[i-1] != b[j-1])? 1: 0; tmin = R_MIN (m[i-1][j] + 1, m[i][j-1] + 1); m[i][j] = R_MIN (tmin, m[i-1][j-1] + cost); } } if (distance) { *distance = m[la][lb]; } if (similarity) { *similarity = (double)1 - (double)(m[la][lb])/(double)(R_MAX(la, lb)); } for(i = 0; i <= la; i++) { free (m[i]); } free (m); return true; }
R_API void r_cons_flush() { const char *tee = I.teefile; if (I.noflush) { return; } if (I.null) { r_cons_reset (); return; } r_cons_filter (); if (I.is_interactive && I.fdout == 1) { /* Use a pager if the output doesn't fit on the terminal window. */ if (I.pager && *I.pager && I.buffer_len > 0 && r_str_char_count (I.buffer, '\n') >= I.rows) { I.buffer[I.buffer_len-1] = 0; r_sys_cmd_str_full (I.pager, I.buffer, NULL, NULL, NULL); r_cons_reset (); } else if (I.buffer_len > CONS_MAX_USER) { #if COUNT_LINES int i, lines = 0; for (i = 0; I.buffer[i]; i++) { if (I.buffer[i] == '\n') { lines ++; } } if (lines > 0 && !r_cons_yesno ('n',"Do you want to print %d lines? (y/N)", lines)) { r_cons_reset (); return; } #else char buf[64]; char *buflen = r_num_units (buf, I.buffer_len); if (buflen && !r_cons_yesno ('n',"Do you want to print %s chars? (y/N)", buflen)) { r_cons_reset (); return; } #endif // fix | more | less problem r_cons_set_raw (1); } } if (tee && *tee) { FILE *d = r_sandbox_fopen (tee, "a+"); if (d) { if (I.buffer_len != fwrite (I.buffer, 1, I.buffer_len, d)) { eprintf ("r_cons_flush: fwrite: error (%s)\n", tee); } fclose (d); } else { eprintf ("Cannot write on '%s'\n", tee); } } r_cons_highlight (I.highlight); // is_html must be a filter, not a write endpoint if (I.is_html) { r_cons_html_print (I.buffer); } else { if (I.is_interactive && !r_sandbox_enable (false)) { if (I.linesleep > 0 && I.linesleep < 1000) { int i = 0; int pagesize = R_MAX (1, I.pagesize); char *ptr = I.buffer; char *nl = strchr (ptr, '\n'); int len = I.buffer_len; I.buffer[I.buffer_len] = 0; r_cons_break_push (NULL, NULL); while (nl && !r_cons_is_breaked ()) { r_cons_write (ptr, nl - ptr + 1); if (!(i % pagesize)) { r_sys_usleep (I.linesleep * 1000); } ptr = nl + 1; nl = strchr (ptr, '\n'); i++; } r_cons_write (ptr, I.buffer + len - ptr); r_cons_break_pop (); } else { r_cons_write (I.buffer, I.buffer_len); } } else { r_cons_write (I.buffer, I.buffer_len); } } r_cons_reset (); if (I.newline) { eprintf ("\n"); I.newline = false; } }
R_API int r_diff_buffers_static(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) { int i, len; int hit = 0; la = R_ABS(la); lb = R_ABS(lb); if (la != lb) { len = R_MIN(la, lb); fprintf(stderr, "Buffer truncated to %d bytes (%d not compared)\n", len, R_ABS(lb-la)); } else len = la; for(i = 0; i<len; i++) { if (a[i]!=b[i]) { hit++; } else { if (hit>0) { struct r_diff_op_t o = { .a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit, .b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit }; d->callback (d, d->user, &o); hit = 0; } } } if (hit>0) { struct r_diff_op_t o = { .a_off = d->off_a+i-hit, .a_buf = a+i-hit, .a_len = hit, .b_off = d->off_b+i-hit, .b_buf = b+i-hit, .b_len = hit }; d->callback (d, d->user, &o); hit = 0; } return 0; } // XXX: temporary files are R_API int r_diff_buffers_radiff(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) { char *ptr, *str, buf[64], oop = 0; int ret, atl, btl, hit; ut8 at[128], bt[128]; ut64 ooa, oob; FILE *fd; hit = atl = btl = 0; ooa = oob = 0LL; oop = -1; r_file_dump (".a", a, la, 0); r_file_dump (".b", b, lb, 0); r_sys_cmd ("radiff -d .a .b | rsc uncolor > .d"); fd = fopen (".d", "r"); while (!feof (fd)) { ut64 oa, ob; // offset int ba, bb = 0; // byte char op; // operation oa = ob = 0LL; if (!fgets (buf, 63, fd)) break; if (feof (fd)) break; str = buf; ptr = strchr (buf, ' '); if (!ptr) continue; *ptr='\0'; sscanf (str, "0x%08"PFMT64x"", &oa); str = r_str_ichr (ptr+1, ' '); if (*str!='|'&&*str!='>'&&*str!='<') { ptr = strchr (str, ' '); if (!ptr) continue; *ptr='\0'; sscanf (str, "%02x", &ba); } else ba = 0; str = r_str_ichr (ptr+1, ' '); ptr = strchr (str, ' '); if (!ptr) continue; *ptr='\0'; sscanf (str, "%c", &op); str = r_str_ichr (ptr+1, ' '); if (str[0]!='0' || str[1]!='x') { ptr = strchr(str, ' '); if (!ptr) continue; *ptr = '\0'; sscanf (str, "%02x", &bb); } str = ptr+1; ptr = strchr (str, '\n'); if (!ptr) continue; *ptr='\0'; sscanf (str, "0x%08"PFMT64x"", &ob); if (oop == op || oop==-1) { if (hit == 0) { ooa = oa; oob = ob; } at[atl] = ba; bt[btl] = bb; switch (op) { case '|': atl++; btl++; break; case '>': btl++; break; case '<': atl++; break; } hit++; } else { if (hit>0) { struct r_diff_op_t o = { .a_off = ooa, .a_buf = at, .a_len = atl, .b_off = oob, .b_buf = bt, .b_len = btl }; ret = d->callback(d, d->user, &o); if (!ret) break; atl = btl = 0; hit = 0; } } oop = op; } if (hit>0) { struct r_diff_op_t o = { .a_off = ooa, .a_buf = at, .a_len = atl, .b_off = oob, .b_buf = bt, .b_len = btl }; if (!d->callback (d, d->user, &o)) { fclose (fd); return 0; } atl = btl = 0; hit = 0; } fclose (fd); unlink (".a"); unlink (".b"); unlink (".d"); return 0; } R_API int r_diff_buffers(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb) { if (d->delta) return r_diff_buffers_delta (d, a, la, b, lb); return r_diff_buffers_static (d, a, la, b, lb); } /* TODO: Move into r_util maybe? */ R_API int r_diff_buffers_distance(RDiff *d, const ut8 *a, ut32 la, const ut8 *b, ut32 lb, ut32 *distance, double *similarity) { int i, j, tmin, **m; ut64 totalsz = 0; if (!a || !b || la < 1 || lb < 1) return R_FALSE; if (la == lb && !memcmp (a, b, la)) { if (distance != NULL) *distance = 0; if (similarity != NULL) *similarity = 1.0; return R_TRUE; } totalsz = sizeof(int*) * (lb+1); for(i = 0; i <= la; i++) { totalsz += ((lb+1) * sizeof(int)); } if (totalsz >= 1024 * 1024 * 512) { char *szstr = r_num_units (NULL, totalsz); eprintf ("Too much memory required (%s) to run distance diff, Use -c.\n", szstr); free (szstr); return R_FALSE; } if ((m = malloc ((la+1) * sizeof(int*))) == NULL) return R_FALSE; for(i = 0; i <= la; i++) { if ((m[i] = malloc ((lb+1) * sizeof(int))) == NULL) { eprintf ("Allocation failed\n"); while (i--) free (m[i]); free (m); return R_FALSE; } } for (i = 0; i <= la; i++) m[i][0] = i; for (j = 0; j <= lb; j++) m[0][j] = j; for (i = 1; i <= la; i++) { for (j = 1; j <= lb; j++) { int cost = (a[i-1] != b[j-1])? 1: 0; tmin = R_MIN (m[i-1][j] + 1, m[i][j-1] + 1); m[i][j] = R_MIN (tmin, m[i-1][j-1] + cost); } } if (distance != NULL) *distance = m[la][lb]; if (similarity != NULL) *similarity = (double)1 - (double)(m[la][lb])/(double)(R_MAX(la, lb)); for(i = 0; i <= la; i++) free (m[i]); free (m); return R_TRUE; }