diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index 5a3d34db4e3..de49e02f483 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -232,15 +232,6 @@ static const char *help_msg_p[] = { NULL }; -static const char *help_msg_pxd[] = { - "Usage:", "pxd[1248] ([len])", "show decimal byte/short/word/dword dumps", - "pxd", "", "show decimal hexdumps", - "pxd2", "", "show shorts hexdump", - "pxd4", "", "show dword hexdump (int)", - "pxd8", "", "show qword hexdump (int)", - NULL -}; - static const char *help_msg_p_equal[] = { "Usage:", "p=[=bep?][qj] [N] ([len]) ([offset]) ", "show entropy/printable chars/chars bars", "e ", "zoom.in", "specify range for zoom", @@ -1751,7 +1742,10 @@ static void cmd_print_format(RzCore *core, const char *_input, const ut8 *block, strcat(x, y); \ x += strlen(y); \ } -static void annotated_hexdump(RzCore *core, const char *str, int len) { +static void annotated_hexdump(RzCore *core, int len) { + if (!len) { + return; + } const int usecolor = rz_config_get_i(core->config, "scr.color"); int nb_cols = rz_config_get_i(core->config, "hex.cols"); core->print->use_comments = rz_config_get_i(core->config, "hex.comments"); @@ -2109,9 +2103,6 @@ RZ_API void rz_core_print_examine(RzCore *core, const char *str) { if (!str[0]) { return; } -#if 0 - Size letters are b(byte), h (halfword), w (word), g (giant, 8 bytes). -#endif switch (str[1]) { case 'b': size = 1; break; case 'h': size = 2; break; @@ -2181,20 +2172,10 @@ RZ_API void rz_core_print_examine(RzCore *core, const char *str) { } } -RZ_API void rz_core_print_cmp(RzCore *core, ut64 from, ut64 to) { - long int delta = 0; - int col = core->cons->columns > 123; - ut8 *b = malloc(core->blocksize); - ut64 addr = core->offset; - memset(b, 0xff, core->blocksize); - delta = addr - from; - rz_io_read_at(core->io, to + delta, b, core->blocksize); - rz_core_print_hexdiff(core, core->offset, core->block, - to + delta, b, core->blocksize, col); - free(b); -} - -static int cmd_print_pxA(RzCore *core, int len, const char *input) { +static bool cmd_print_pxA(RzCore *core, int len, RzOutputMode mode) { + if (!len) { + return true; + } RzConsPrintablePalette *pal = &core->cons->context->pal; int show_offset = true; int cols = rz_config_get_i(core->config, "hex.cols"); @@ -2209,21 +2190,27 @@ static int cmd_print_pxA(RzCore *core, int len, const char *input) { RzAnalysisOp op; ut8 *data; int datalen; - if (*input == 'v') { + switch (mode) { + case RZ_OUTPUT_MODE_LONG: datalen = cols * 8 * core->cons->rows; data = malloc(datalen); rz_io_read_at(core->io, core->offset, data, datalen); len = datalen; - } else { + break; + case RZ_OUTPUT_MODE_STANDARD: data = core->block; datalen = core->blocksize; + break; + default: + rz_warn_if_reached(); + return false; } if (len < 1) { len = datalen; } if (len < 0 || len > datalen) { eprintf("Invalid length\n"); - return 0; + return false; } if (onechar) { cols *= 4; @@ -4013,10 +4000,7 @@ static int bbcmp(RzAnalysisBlock *a, RzAnalysisBlock *b) { } /* TODO: integrate this into rz_analysis */ -static void _pointer_table(RzCore *core, ut64 origin, ut64 offset, const ut8 *buf, int len, int step, int mode) { - int i; - ut64 addr; - st32 *delta; // only for step == 4 +static void _pointer_table(RzCore *core, ut64 origin, ut64 offset, const ut8 *buf, int len, int step, RzOutputMode mode) { if (step < 1) { step = 4; } @@ -4025,29 +4009,16 @@ static void _pointer_table(RzCore *core, ut64 origin, ut64 offset, const ut8 *bu return; } if (origin != offset) { - switch (mode) { - case '*': + if (mode == RZ_OUTPUT_MODE_RIZIN) { rz_cons_printf("CC-@ 0x%08" PFMT64x "\n", origin); rz_cons_printf("CC switch table @ 0x%08" PFMT64x "\n", origin); rz_cons_printf("axd 0x%" PFMT64x " @ 0x%08" PFMT64x "\n", origin, offset); - break; - case '.': - rz_meta_del(core->analysis, RZ_META_TYPE_COMMENT, origin, 1); - rz_meta_set_string(core->analysis, RZ_META_TYPE_COMMENT, origin, "switch table"); - rz_core_cmdf(core, "f switch.0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", origin, origin); - rz_core_cmdf(core, "f jmptbl.0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", offset, offset); // origin, origin); - rz_analysis_xrefs_set(core->analysis, offset, origin, RZ_ANALYSIS_XREF_TYPE_DATA); - break; } - } else if (mode == '.') { - rz_meta_del(core->analysis, RZ_META_TYPE_COMMENT, origin, 1); - rz_meta_set_string(core->analysis, RZ_META_TYPE_COMMENT, offset, "switch basic block"); - rz_core_cmdf(core, "f switch.0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", offset, offset); // basic block @ 0x%08"PFMT64x "\n", offset); } int n = 0; - for (i = 0; (i + sizeof(st32)) <= len; i += step, n++) { - delta = (st32 *)(buf + i); - addr = offset + *delta; + for (int i = 0; (i + sizeof(st32)) <= len; i += step, n++) { + st32 *delta = (st32 *)(buf + i); + ut64 addr = offset + *delta; if (!rz_io_is_valid_offset(core->io, addr, 0)) { // Lets check for jmptbl with not relative addresses // Like: jmp dword [eax*4 + jmptbl.0x5435345] @@ -4056,22 +4027,13 @@ static void _pointer_table(RzCore *core, ut64 origin, ut64 offset, const ut8 *bu } addr = *delta; } - if (mode == '*') { + if (mode == RZ_OUTPUT_MODE_RIZIN) { rz_cons_printf("af case.%d.0x%" PFMT64x " 0x%08" PFMT64x "\n", n, offset, addr); rz_cons_printf("ax 0x%" PFMT64x " @ 0x%08" PFMT64x "\n", offset, addr); rz_cons_printf("ax 0x%" PFMT64x " @ 0x%08" PFMT64x "\n", addr, offset); // wrong, but useful because forward xrefs dont work :? // FIXME: "aho" doesn't accept anything here after the "case" word rz_cons_printf("aho case 0x%" PFMT64x " 0x%08" PFMT64x " @ 0x%08" PFMT64x "\n", (ut64)i, addr, offset + i); // wrong, but useful because forward xrefs dont work :? rz_cons_printf("ahs %d @ 0x%08" PFMT64x "\n", step, offset + i); - } else if (mode == '.') { - const char *case_name = rz_str_newf("case.%d.0x%" PFMT64x, n, offset); - rz_core_analysis_function_add(core, case_name, addr, false); - rz_analysis_xrefs_set(core->analysis, addr, offset, RZ_ANALYSIS_XREF_TYPE_NULL); - rz_analysis_xrefs_set(core->analysis, offset, addr, RZ_ANALYSIS_XREF_TYPE_NULL); // wrong, but useful because forward xrefs dont work :? - const char *case_comment = rz_str_newf("case %d:", n); - rz_core_meta_comment_add(core, case_comment, addr); - rz_analysis_hint_set_type(core->analysis, offset + i, RZ_ANALYSIS_OP_TYPE_CASE); // wrong, but useful because forward xrefs dont work :? - rz_analysis_hint_set_size(core->analysis, offset + i, step); } else { rz_cons_printf("0x%08" PFMT64x " -> 0x%08" PFMT64x "\n", offset + i, addr); } @@ -4493,90 +4455,85 @@ static char *__op_refs(RzCore *core, RzAnalysisOp *op, int n) { return res; } -static void cmd_pxr(RzCore *core, int len, int mode, int wordsize, const char *arg) { - PJ *pj = NULL; - RzTable *t = NULL; - if (mode == ',') { - t = rz_table_new(); +static inline char *__refs(RzCore *core, ut64 x) { + if (!core->print->hasrefs) { + return NULL; + } + + char *refs = core->print->hasrefs(core->print->user, x, true); + if (RZ_STR_ISNOTEMPTY(refs)) { + rz_str_trim(refs); + } else { + RZ_FREE(refs); + } + return refs; +} + +static bool cmd_pxr(RzCore *core, int len, RzCmdStateOutput *state, int wordsize, const char *query) { + if (!len) { + return true; + } + RzStrBuf *sb = rz_strbuf_new(NULL); + if (!sb) { + return false; + } + + const ut8 *buf = core->block; + + bool be = core->analysis->big_endian; + int end = RZ_MIN(core->blocksize, len); + int bitsize = wordsize * 8; + RzOutputMode mode = state->mode; + if (mode == RZ_OUTPUT_MODE_TABLE) { + RzTable *t = state->d.t; RzTableColumnType *n = rz_table_type("number"); RzTableColumnType *s = rz_table_type("string"); rz_table_add_column(t, n, "addr", 0); rz_table_add_column(t, n, "value", 0); rz_table_add_column(t, s, "refs", 0); - } - if (mode == 'j') { - pj = pj_new(); - if (!pj) { - return; - } - } - if (mode == 'j' || mode == ',' || mode == '*' || mode == 'q') { - size_t i; - const int be = core->analysis->big_endian; - if (pj) { - pj_a(pj); + for (ut64 i = 0; i + wordsize < end; i += wordsize) { + ut64 addr = core->offset + i; + ut64 val = rz_read_ble(buf + i, be, bitsize); + char *refs = __refs(core, val); + rz_table_add_rowf(t, "xxs", addr, val, refs); + RZ_FREE(refs); } - const ut8 *buf = core->block; - - bool withref = false; - int end = RZ_MIN(core->blocksize, len); - int bitsize = wordsize * 8; - for (i = 0; i + wordsize < end; i += wordsize) { + rz_table_query(t, query); + } else if (mode == RZ_OUTPUT_MODE_JSON) { + PJ *pj = state->d.pj; + const int hex_depth = (int)rz_config_get_i(core->config, "hex.depth"); + pj_a(pj); + for (ut64 i = 0; i + wordsize < end; i += wordsize) { ut64 addr = core->offset + i; ut64 val = rz_read_ble(buf + i, be, bitsize); - if (pj) { - pj_o(pj); - pj_kn(pj, "addr", addr); - pj_kn(pj, "value", val); - } + pj_o(pj); + pj_kn(pj, "addr", addr); + pj_kn(pj, "value", val); + char *refs = __refs(core, val); + if (refs) { + char *refstr = rz_str_escape(refs); + pj_ks(pj, "refstr", rz_str_trim_head_ro(refstr)); + free(refstr); - // XXX: this only works in little endian - withref = false; - char *refs = NULL; - if (core->print->hasrefs) { - char *rstr = core->print->hasrefs(core->print->user, val, true); - if (RZ_STR_ISNOTEMPTY(rstr)) { - rz_str_trim(rstr); - if (pj) { - char *ns = rz_str_escape(rstr); - pj_ks(pj, "refstr", rz_str_trim_head_ro(ns)); - pj_k(pj, "ref"); - const int hex_depth = rz_config_get_i(core->config, "hex.depth"); - free(rz_core_analysis_hasrefs_to_depth(core, val, pj, hex_depth)); - pj_end(pj); - free(ns); - } - withref = true; - } - refs = rstr; - } - if (mode == '*' && RZ_STR_ISNOTEMPTY(refs)) { - // Show only the mapped ones? - rz_cons_printf("f pxr.%" PFMT64x " @ 0x%" PFMT64x "\n", val, addr); - } else if (mode == 'q' && RZ_STR_ISNOTEMPTY(refs)) { - rz_cons_printf("%s\n", refs); - } - if (t) { - rz_table_add_rowf(t, "xxs", addr, val, refs); - } - RZ_FREE(refs); - if (!withref && pj) { - pj_end(pj); + pj_k(pj, "ref"); + free(rz_core_analysis_hasrefs_to_depth(core, val, pj, hex_depth)); } + pj_end(pj); } - if (t) { - rz_table_query(t, arg ? arg + 1 : NULL); - char *s = rz_table_tostring(t); - rz_cons_println(s); - free(s); - rz_table_free(t); + pj_end(pj); + } else if (mode == RZ_OUTPUT_MODE_QUIET) { + for (ut64 i = 0; i + wordsize < end; i += wordsize) { + ut64 val = rz_read_ble(buf + i, be, bitsize); + char *refs = __refs(core, val); + rz_strbuf_appendf(sb, "%s\n", refs); } - if (pj) { - pj_end(pj); - rz_cons_println(pj_string(pj)); - pj_free(pj); + } else if (mode == RZ_OUTPUT_MODE_RIZIN) { + for (ut64 i = 0; i + wordsize < end; i += wordsize) { + ut64 addr = core->offset + i; + ut64 val = rz_read_ble(buf + i, be, bitsize); + rz_strbuf_appendf(sb, "f pxr.%" PFMT64x " @ 0x%" PFMT64x "\n", val, addr); } - } else { + } else if (mode == RZ_OUTPUT_MODE_STANDARD) { const int ocols = core->print->cols; int bitsize = core->rasm->bits; /* Thumb is 16bit arm but handles 32bit data */ @@ -4585,14 +4542,22 @@ static void cmd_pxr(RzCore *core, int len, int mode, int wordsize, const char *a } core->print->cols = 1; core->print->flags |= RZ_PRINT_FLAGS_REFS; - rz_cons_break_push(NULL, NULL); - rz_core_print_hexdump(core, core->offset, - core->block, RZ_MIN(len, core->blocksize), - wordsize * 8, bitsize / 8, 1); - rz_cons_break_pop(); + rz_strbuf_append(sb, rz_print_hexdump_str(core->print, core->offset, core->block, RZ_MIN(len, core->blocksize), wordsize * 8, bitsize / 8, 1)); core->print->flags &= ~RZ_PRINT_FLAGS_REFS; core->print->cols = ocols; + } else { + rz_warn_if_reached(); + rz_strbuf_free(sb); + return false; + } + if (mode == RZ_OUTPUT_MODE_RIZIN || mode == RZ_OUTPUT_MODE_STANDARD || mode == RZ_OUTPUT_MODE_QUIET) { + char *res = rz_strbuf_drain(sb); + rz_cons_print(res); + free(res); + } else { + rz_strbuf_free(sb); } + return true; } static void core_print_2bpp_row(const ut8 *buf, bool useColor) { @@ -5575,509 +5540,12 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { } rz_cons_break_push(NULL, NULL); switch (input[1]) { - case 'j': // "pxj" - rz_core_print_jsondump(core, core->block, core->blocksize, 8); - break; case '/': // "px/" rz_core_print_examine(core, input + 2); break; case '?': - rz_core_cmd_help(core, help_msg_px); - break; - case '0': // "px0" - if (l) { - int len = rz_str_nlen((const char *)core->block, core->blocksize); - rz_print_bytes(core->print, core->block, len, "%02x"); - } - break; - case 'a': // "pxa" - if (l != 0) { - if (len % 16) { - len += 16 - (len % 16); - } - annotated_hexdump(core, input + 2, len); - } - break; - case 'x': // "pxx" - if (l != 0) { - core->print->flags |= RZ_PRINT_FLAGS_NONHEX; - rz_core_print_hexdump(core, core->offset, - core->block, len, 8, 1, 1); - core->print->flags &= ~RZ_PRINT_FLAGS_NONHEX; - } - break; - case 'X': // "pxX" - if (l != 0) { - ut8 *buf = calloc(len, 4); - if (buf) { - rz_io_read_at(core->io, core->offset, buf, len * 4); - core->print->flags |= RZ_PRINT_FLAGS_NONHEX; - rz_core_print_hexdump(core, core->offset, buf, len * 4, 8, 1, 1); - core->print->flags &= ~RZ_PRINT_FLAGS_NONHEX; - free(buf); - } - } - break; - case 'A': // "pxA" - if (input[2] == '?') { - rz_core_cmd_help(core, help_msg_pxA); - } else if (l) { - cmd_print_pxA(core, len, input + 2); - } - break; - case 'b': // "pxb" - if (l) { - ut32 n; - int i, c; - char buf[32]; - for (i = c = 0; i < len; i++, c++) { - if (c == 0) { - ut64 ea = core->offset + i; - if (core->print->pava) { - ut64 va = rz_io_p2v(core->io, ea); - if (va != UT64_MAX) { - ea = va; - } - } - rz_print_section(core->print, ea); - rz_print_offset(core->print, ea, 0, 0, 0, 0, NULL); - } - rz_str_bits(buf, core->block + i, 8, NULL); - - // split bits - memmove(buf + 5, buf + 4, 5); - buf[4] = 0; - - rz_print_cursor(core->print, i, 1, 1); - rz_cons_printf("%s.%s ", buf, buf + 5); - rz_print_cursor(core->print, i, 1, 0); - if (c == 3) { - const ut8 *b = core->block + i - 3; - int (*k)(const ut8 *, int) = cmd_pxb_k; - char (*p)(char) = cmd_pxb_p; - - n = k(b, 0) | k(b, 1) | k(b, 2) | k(b, 3); - rz_cons_printf("0x%08x %c%c%c%c\n", - n, p(b[0]), p(b[1]), p(b[2]), p(b[3])); - c = -1; - } - } - } - break; - case 'c': // "pxc" - { - int ocomments = core->print->use_comments; - core->print->use_comments = core->print->flags & RZ_PRINT_FLAGS_COMMENT; - if (l) { - ut64 from = rz_config_get_i(core->config, "diff.from"); - ut64 to = rz_config_get_i(core->config, "diff.to"); - if (from == to && !from) { - rz_core_block_size(core, len); - len = core->blocksize; - rz_core_print_hexdump(core, core->offset, - core->block, core->blocksize, 16, 1, 1); - } else { - rz_core_print_cmp(core, from, to); - } - core->num->value = len; - } - core->print->use_comments = ocomments; - } break; - case 'i': // "pxi" - if (l != 0) { - core->print->show_offset = rz_config_get_i(core->config, "hex.offset"); - rz_print_hexii(core->print, core->offset, core->block, - core->blocksize, rz_config_get_i(core->config, "hex.cols")); - } - break; - case 'o': // "pxo" - if (l != 0) { - rz_core_print_hexdump(core, core->offset, - core->block, len, 8, 1, 1); - } - break; - case 't': // "pxt" - { - ut64 origin = core->offset; - const char *arg = strchr(input, ' '); - if (arg) { - origin = rz_num_math(core->num, arg + 1); - } - // _pointer_table does rz_core_cmd with @, so it modifies core->block - // and this results in an UAF access when iterating over the jmptable - // so we do a new allocation to avoid that issue - ut8 *block = calloc(len, 1); - if (block) { - memcpy(block, core->block, len); - _pointer_table(core, origin, core->offset, block, len, 4, input[2]); - free(block); - } - } break; - case 'd': // "pxd" - if (input[2] == '?') { - rz_core_cmd_help(core, help_msg_pxd); - } else if (l != 0) { - switch (input[2]) { - case '1': - // 1 byte signed words (byte) - if (input[3] == 'j') { - rz_core_print_jsondump(core, core->block, - len, 8); - } else { - rz_core_print_hexdump(core, core->offset, - core->block, len, -1, 4, 1); - } - break; - case '2': - // 2 byte signed words (short) - if (input[3] == 'j') { - rz_core_print_jsondump(core, core->block, - len, 16); - } else { - rz_core_print_hexdump(core, core->offset, - core->block, len, -10, 2, 1); - } - break; - case '8': - if (input[3] == 'j') { - rz_core_print_jsondump(core, core->block, - len, 64); - } else { - rz_core_print_hexdump(core, core->offset, - core->block, len, -8, 4, 1); - } - break; - case '4': - case ' ': - case 'j': - case 0: - // 4 byte signed words - if (input[2] == 'j' || (input[2] && input[3] == 'j')) { - rz_core_print_jsondump(core, core->block, - len, 32); - } else { - rz_core_print_hexdump(core, core->offset, - core->block, len, 10, 4, 1); - } - break; - default: - rz_core_cmd_help(core, help_msg_pxd); - break; - } - } - break; - case 'w': // "pxw" - if (l != 0) { - if (input[2] == 'j') { - rz_core_print_jsondump(core, core->block, len, 32); - } else { - rz_core_print_hexdump(core, core->offset, core->block, len, 32, 4, 1); - } - } - break; - case 'W': // "pxW" - if (l) { - bool printOffset = (input[2] != 'q' && rz_config_get_i(core->config, "hex.offset")); - len = len - (len % 4); - for (i = 0; i < len; i += 4) { - const char *a, *b; - char *fn; - RzPrint *p = core->print; - RzFlagItem *f; - ut32 v = rz_read_ble32(core->block + i, core->print->big_endian); - if (p && p->colorfor) { - a = p->colorfor(p->user, v, true); - if (a && *a) { - b = Color_RESET; - } else { - a = b = ""; - } - } else { - a = b = ""; - } - f = rz_flag_get_at(core->flags, v, true); - fn = NULL; - if (f) { - st64 delta = (v - f->offset); - if (delta >= 0 && delta < 8192) { - if (v == f->offset) { - fn = strdup(f->name); - } else { - fn = rz_str_newf("%s+%" PFMT64d, - f->name, v - f->offset); - } - } - } - if (printOffset) { - rz_print_section(core->print, core->offset + i); - rz_cons_printf("0x%08" PFMT64x " %s0x%08" PFMT64x "%s%s%s\n", - (ut64)core->offset + i, a, (ut64)v, - b, fn ? " " : "", fn ? fn : ""); - } else { - rz_cons_printf("%s0x%08" PFMT64x "%s\n", a, (ut64)v, b); - } - free(fn); - } - } - break; - case 'r': // "pxr" - if (l) { - int mode = input[2]; - int wordsize = rz_analysis_get_address_bits(core->analysis) / 8; - if (mode == '?') { - eprintf("Usage: pxr[1248][*,jq] [length]\n"); - break; - } - if (mode && isdigit(mode)) { - char tmp[2] = { input[2], 0 }; - wordsize = atoi(tmp); - mode = input[3]; - } - switch (wordsize) { - case 1: - case 2: - case 4: - case 8: - cmd_pxr(core, len, mode, wordsize, mode ? strchr(input, mode) : NULL); - break; - default: - eprintf("Invalid word size. Use 1, 2, 4 or 8.\n"); - break; - } - } - break; - case 'h': // "pxh" - if (l) { - if (input[2] == 'j') { - rz_core_print_jsondump(core, core->block, len, 16); - } else { - rz_core_print_hexdump(core, core->offset, - core->block, len, 32, 2, 1); - } - } - break; - case 'H': // "pxH" - if (l != 0) { - len = len - (len % 2); - for (i = 0; i < len; i += 2) { - const char *a, *b; - char *fn; - RzPrint *p = core->print; - RzFlagItem *f; - ut64 v = (ut64)rz_read_ble16(core->block + i, p->big_endian); - if (p && p->colorfor) { - a = p->colorfor(p->user, v, true); - if (a && *a) { - b = Color_RESET; - } else { - a = b = ""; - } - } else { - a = b = ""; - } - f = rz_flag_get_at(core->flags, v, true); - fn = NULL; - if (f) { - st64 delta = (v - f->offset); - if (delta >= 0 && delta < 8192) { - if (v == f->offset) { - fn = strdup(f->name); - } else { - fn = rz_str_newf("%s+%" PFMT64d, f->name, v - f->offset); - } - } - } - rz_cons_printf("0x%08" PFMT64x " %s0x%04" PFMT64x "%s %s\n", - (ut64)core->offset + i, a, v, b, fn ? fn : ""); - free(fn); - } - } - break; - case 'q': // "pxq" - if (l) { - if (input[2] == 'j') { - rz_core_print_jsondump(core, core->block, len, 64); - } else { - rz_core_print_hexdump(core, core->offset, core->block, len, 64, 8, 1); - } - } - break; - case 'Q': // "pxQ" - // TODO. show if flag name, or inside function - if (l) { - bool printOffset = (input[2] != 'q' && rz_config_get_i(core->config, "hex.offset")); - len = len - (len % 8); - for (i = 0; i < len; i += 8) { - const char *a, *b; - char *fn; - RzPrint *p = core->print; - RzFlagItem *f; - ut64 v = rz_read_ble64(core->block + i, p->big_endian); - if (p && p->colorfor) { - a = p->colorfor(p->user, v, true); - if (a && *a) { - b = Color_RESET; - } else { - a = b = ""; - } - } else { - a = b = ""; - } - f = rz_flag_get_at(core->flags, v, true); - fn = NULL; - if (f) { - st64 delta = (v - f->offset); - if (delta >= 0 && delta < 8192) { - if (v == f->offset) { - fn = strdup(f->name); - } else { - fn = rz_str_newf("%s+%" PFMT64d, f->name, v - f->offset); - } - } - } - if (printOffset) { - rz_print_section(core->print, core->offset + i); - rz_cons_printf("0x%08" PFMT64x " %s0x%016" PFMT64x "%s %s\n", - (ut64)core->offset + i, a, v, b, fn ? fn : ""); - } else { - rz_cons_printf("%s0x%016" PFMT64x "%s\n", a, v, b); - } - free(fn); - } - } - break; - case 's': // "pxs" - if (l) { - core->print->flags |= RZ_PRINT_FLAGS_SPARSE; - rz_core_print_hexdump(core, core->offset, core->block, len, 16, 1, 1); - core->print->flags &= (((ut32)-1) & (~RZ_PRINT_FLAGS_SPARSE)); - } - break; - case 'e': // "pxe" // emoji dump - if (l != 0) { - int j; - char emoji[] = { - '\x8c', '\x80', '\x8c', '\x82', '\x8c', '\x85', '\x8c', '\x88', - '\x8c', '\x99', '\x8c', '\x9e', '\x8c', '\x9f', '\x8c', '\xa0', - '\x8c', '\xb0', '\x8c', '\xb1', '\x8c', '\xb2', '\x8c', '\xb3', - '\x8c', '\xb4', '\x8c', '\xb5', '\x8c', '\xb7', '\x8c', '\xb8', - '\x8c', '\xb9', '\x8c', '\xba', '\x8c', '\xbb', '\x8c', '\xbc', - '\x8c', '\xbd', '\x8c', '\xbe', '\x8c', '\xbf', '\x8d', '\x80', - '\x8d', '\x81', '\x8d', '\x82', '\x8d', '\x83', '\x8d', '\x84', - '\x8d', '\x85', '\x8d', '\x86', '\x8d', '\x87', '\x8d', '\x88', - '\x8d', '\x89', '\x8d', '\x8a', '\x8d', '\x8b', '\x8d', '\x8c', - '\x8d', '\x8d', '\x8d', '\x8e', '\x8d', '\x8f', '\x8d', '\x90', - '\x8d', '\x91', '\x8d', '\x92', '\x8d', '\x93', '\x8d', '\x94', - '\x8d', '\x95', '\x8d', '\x96', '\x8d', '\x97', '\x8d', '\x98', - '\x8d', '\x9c', '\x8d', '\x9d', '\x8d', '\x9e', '\x8d', '\x9f', - '\x8d', '\xa0', '\x8d', '\xa1', '\x8d', '\xa2', '\x8d', '\xa3', - '\x8d', '\xa4', '\x8d', '\xa5', '\x8d', '\xa6', '\x8d', '\xa7', - '\x8d', '\xa8', '\x8d', '\xa9', '\x8d', '\xaa', '\x8d', '\xab', - '\x8d', '\xac', '\x8d', '\xad', '\x8d', '\xae', '\x8d', '\xaf', - '\x8d', '\xb0', '\x8d', '\xb1', '\x8d', '\xb2', '\x8d', '\xb3', - '\x8d', '\xb4', '\x8d', '\xb5', '\x8d', '\xb6', '\x8d', '\xb7', - '\x8d', '\xb8', '\x8d', '\xb9', '\x8d', '\xba', '\x8d', '\xbb', - '\x8d', '\xbc', '\x8e', '\x80', '\x8e', '\x81', '\x8e', '\x82', - '\x8e', '\x83', '\x8e', '\x84', '\x8e', '\x85', '\x8e', '\x88', - '\x8e', '\x89', '\x8e', '\x8a', '\x8e', '\x8b', '\x8e', '\x8c', - '\x8e', '\x8d', '\x8e', '\x8e', '\x8e', '\x8f', '\x8e', '\x92', - '\x8e', '\x93', '\x8e', '\xa0', '\x8e', '\xa1', '\x8e', '\xa2', - '\x8e', '\xa3', '\x8e', '\xa4', '\x8e', '\xa5', '\x8e', '\xa6', - '\x8e', '\xa7', '\x8e', '\xa8', '\x8e', '\xa9', '\x8e', '\xaa', - '\x8e', '\xab', '\x8e', '\xac', '\x8e', '\xad', '\x8e', '\xae', - '\x8e', '\xaf', '\x8e', '\xb0', '\x8e', '\xb1', '\x8e', '\xb2', - '\x8e', '\xb3', '\x8e', '\xb4', '\x8e', '\xb5', '\x8e', '\xb7', - '\x8e', '\xb8', '\x8e', '\xb9', '\x8e', '\xba', '\x8e', '\xbb', - '\x8e', '\xbd', '\x8e', '\xbe', '\x8e', '\xbf', '\x8f', '\x80', - '\x8f', '\x81', '\x8f', '\x82', '\x8f', '\x83', '\x8f', '\x84', - '\x8f', '\x86', '\x8f', '\x87', '\x8f', '\x88', '\x8f', '\x89', - '\x8f', '\x8a', '\x90', '\x80', '\x90', '\x81', '\x90', '\x82', - '\x90', '\x83', '\x90', '\x84', '\x90', '\x85', '\x90', '\x86', - '\x90', '\x87', '\x90', '\x88', '\x90', '\x89', '\x90', '\x8a', - '\x90', '\x8b', '\x90', '\x8c', '\x90', '\x8d', '\x90', '\x8e', - '\x90', '\x8f', '\x90', '\x90', '\x90', '\x91', '\x90', '\x92', - '\x90', '\x93', '\x90', '\x94', '\x90', '\x95', '\x90', '\x96', - '\x90', '\x97', '\x90', '\x98', '\x90', '\x99', '\x90', '\x9a', - '\x90', '\x9b', '\x90', '\x9c', '\x90', '\x9d', '\x90', '\x9e', - '\x90', '\x9f', '\x90', '\xa0', '\x90', '\xa1', '\x90', '\xa2', - '\x90', '\xa3', '\x90', '\xa4', '\x90', '\xa5', '\x90', '\xa6', - '\x90', '\xa7', '\x90', '\xa8', '\x90', '\xa9', '\x90', '\xaa', - '\x90', '\xab', '\x90', '\xac', '\x90', '\xad', '\x90', '\xae', - '\x90', '\xaf', '\x90', '\xb0', '\x90', '\xb1', '\x90', '\xb2', - '\x90', '\xb3', '\x90', '\xb4', '\x90', '\xb5', '\x90', '\xb6', - '\x90', '\xb7', '\x90', '\xb8', '\x90', '\xb9', '\x90', '\xba', - '\x90', '\xbb', '\x90', '\xbc', '\x90', '\xbd', '\x90', '\xbe', - '\x91', '\x80', '\x91', '\x82', '\x91', '\x83', '\x91', '\x84', - '\x91', '\x85', '\x91', '\x86', '\x91', '\x87', '\x91', '\x88', - '\x91', '\x89', '\x91', '\x8a', '\x91', '\x8b', '\x91', '\x8c', - '\x91', '\x8d', '\x91', '\x8e', '\x91', '\x8f', '\x91', '\x90', - '\x91', '\x91', '\x91', '\x92', '\x91', '\x93', '\x91', '\x94', - '\x91', '\x95', '\x91', '\x96', '\x91', '\x97', '\x91', '\x98', - '\x91', '\x99', '\x91', '\x9a', '\x91', '\x9b', '\x91', '\x9c', - '\x91', '\x9d', '\x91', '\x9e', '\x91', '\x9f', '\x91', '\xa0', - '\x91', '\xa1', '\x91', '\xa2', '\x91', '\xa3', '\x91', '\xa4', - '\x91', '\xa5', '\x91', '\xa6', '\x91', '\xa7', '\x91', '\xa8', - '\x91', '\xa9', '\x91', '\xaa', '\x91', '\xae', '\x91', '\xaf', - '\x91', '\xba', '\x91', '\xbb', '\x91', '\xbc', '\x91', '\xbd', - '\x91', '\xbe', '\x91', '\xbf', '\x92', '\x80', '\x92', '\x81', - '\x92', '\x82', '\x92', '\x83', '\x92', '\x84', '\x92', '\x85' - }; - int cols = core->print->cols; - if (cols < 1) { - cols = 1; - } - for (i = 0; i < len; i += cols) { - rz_print_addr(core->print, core->offset + i); - for (j = i; j < i + cols; j += 1) { - ut8 *p = (ut8 *)core->block + j; - if (j < len) { - rz_cons_printf("\xf0\x9f%c%c ", emoji[*p * 2], emoji[*p * 2 + 1]); - } else { - rz_cons_print(" "); - } - } - rz_cons_print(" "); - for (j = i; j < len && j < i + cols; j += 1) { - ut8 *p = (ut8 *)core->block + j; - rz_print_byte(core->print, "%c", j, *p); - } - rz_cons_newline(); - } - } - break; - case 'l': // "pxl" - len = core->print->cols * len; - /* fallthrough */ default: - if (l) { - ut64 from = rz_config_get_i(core->config, "diff.from"); - ut64 to = rz_config_get_i(core->config, "diff.to"); - if (from == to && !from) { - const char *sp = NULL; - if (input[1] == '.') { - sp = input + 2; - } - if (IS_DIGIT(input[1])) { - sp = input + 1; - } - if (sp) { - int n = (int)rz_num_math(core->num, rz_str_trim_head_ro(sp)); - if (!n) { - goto beach; - } - len = n; - } - if (!rz_core_block_size(core, len)) { - len = core->blocksize; - } - rz_core_block_read(core); - rz_core_print_hexdump(core, rz_core_pava(core, core->offset), - core->block, len, 16, 1, 1); - } else { - rz_core_print_cmp(core, from, to); - } - core->num->value = len; - } + rz_core_cmd_help(core, help_msg_px); break; } rz_cons_break_pop(); @@ -6199,7 +5667,8 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { } RZ_IPI int rz_cmd_hexdump(void *data, const char *input) { - return rz_cmd_print(data, input - 1); + // TODO: Use the API directly + return rz_core_cmdf(data, "px%s", input); } static int lenof(ut64 off, int two) { @@ -6402,6 +5871,344 @@ RZ_IPI RzCmdStatus rz_print_utf32be_handler(RzCore *core, int argc, const char * return RZ_CMD_STATUS_OK; } +RZ_IPI RzCmdStatus rz_print_hexdump_annotated_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (len % 16) { + len += 16 - (len % 16); + } + annotated_hexdump(core, len); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_op_analysis_color_map_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(cmd_print_pxA(core, len, state->mode)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_bits_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (!len) { + return RZ_CMD_STATUS_OK; + } + + char buf[32]; + for (int i = 0, c = 0; i < len; i++, c++) { + if (c == 0) { + ut64 ea = core->offset + i; + if (core->print->pava) { + ut64 va = rz_io_p2v(core->io, ea); + if (va != UT64_MAX) { + ea = va; + } + } + char *string = rz_print_section_str(core->print, ea); + rz_cons_print(string); + free(string); + rz_print_offset(core->print, ea, 0, 0, 0, 0, NULL); + } + rz_str_bits(buf, core->block + i, 8, NULL); + + // split bits + memmove(buf + 5, buf + 4, 5); + buf[4] = 0; + + rz_print_cursor(core->print, i, 1, 1); + rz_cons_printf("%s.%s ", buf, buf + 5); + rz_print_cursor(core->print, i, 1, 0); + if (c == 3) { + const ut8 *b = core->block + i - 3; + int (*k)(const ut8 *, int) = cmd_pxb_k; + char (*p)(char) = cmd_pxb_p; + + int n = k(b, 0) | k(b, 1) | k(b, 2) | k(b, 3); + rz_cons_printf("0x%08x %c%c%c%c\n", + n, p(b[0]), p(b[1]), p(b[2]), p(b[3])); + c = -1; + } + } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_comments_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_hexdump_or_hexdiff(core, RZ_OUTPUT_MODE_STANDARD, core->offset, len, true)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer_common_handler(RzCore *core, int argc, const char **argv, + RzCmdStateOutput *state, ut8 n) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_dump(core, state->mode, core->offset, n, len, RZ_CORE_PRINT_FORMAT_TYPE_INTEGER)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_signed_integer_common_handler(core, argc, argv, state, 1); +} +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_signed_integer_common_handler(core, argc, argv, state, 2); +} +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_signed_integer_common_handler(core, argc, argv, state, 4); +} +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_signed_integer_common_handler(core, argc, argv, state, 8); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_emoji_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (!len) { + return RZ_CMD_STATUS_OK; + } + static const char emoji[] = { + '\x8c', '\x80', '\x8c', '\x82', '\x8c', '\x85', '\x8c', '\x88', + '\x8c', '\x99', '\x8c', '\x9e', '\x8c', '\x9f', '\x8c', '\xa0', + '\x8c', '\xb0', '\x8c', '\xb1', '\x8c', '\xb2', '\x8c', '\xb3', + '\x8c', '\xb4', '\x8c', '\xb5', '\x8c', '\xb7', '\x8c', '\xb8', + '\x8c', '\xb9', '\x8c', '\xba', '\x8c', '\xbb', '\x8c', '\xbc', + '\x8c', '\xbd', '\x8c', '\xbe', '\x8c', '\xbf', '\x8d', '\x80', + '\x8d', '\x81', '\x8d', '\x82', '\x8d', '\x83', '\x8d', '\x84', + '\x8d', '\x85', '\x8d', '\x86', '\x8d', '\x87', '\x8d', '\x88', + '\x8d', '\x89', '\x8d', '\x8a', '\x8d', '\x8b', '\x8d', '\x8c', + '\x8d', '\x8d', '\x8d', '\x8e', '\x8d', '\x8f', '\x8d', '\x90', + '\x8d', '\x91', '\x8d', '\x92', '\x8d', '\x93', '\x8d', '\x94', + '\x8d', '\x95', '\x8d', '\x96', '\x8d', '\x97', '\x8d', '\x98', + '\x8d', '\x9c', '\x8d', '\x9d', '\x8d', '\x9e', '\x8d', '\x9f', + '\x8d', '\xa0', '\x8d', '\xa1', '\x8d', '\xa2', '\x8d', '\xa3', + '\x8d', '\xa4', '\x8d', '\xa5', '\x8d', '\xa6', '\x8d', '\xa7', + '\x8d', '\xa8', '\x8d', '\xa9', '\x8d', '\xaa', '\x8d', '\xab', + '\x8d', '\xac', '\x8d', '\xad', '\x8d', '\xae', '\x8d', '\xaf', + '\x8d', '\xb0', '\x8d', '\xb1', '\x8d', '\xb2', '\x8d', '\xb3', + '\x8d', '\xb4', '\x8d', '\xb5', '\x8d', '\xb6', '\x8d', '\xb7', + '\x8d', '\xb8', '\x8d', '\xb9', '\x8d', '\xba', '\x8d', '\xbb', + '\x8d', '\xbc', '\x8e', '\x80', '\x8e', '\x81', '\x8e', '\x82', + '\x8e', '\x83', '\x8e', '\x84', '\x8e', '\x85', '\x8e', '\x88', + '\x8e', '\x89', '\x8e', '\x8a', '\x8e', '\x8b', '\x8e', '\x8c', + '\x8e', '\x8d', '\x8e', '\x8e', '\x8e', '\x8f', '\x8e', '\x92', + '\x8e', '\x93', '\x8e', '\xa0', '\x8e', '\xa1', '\x8e', '\xa2', + '\x8e', '\xa3', '\x8e', '\xa4', '\x8e', '\xa5', '\x8e', '\xa6', + '\x8e', '\xa7', '\x8e', '\xa8', '\x8e', '\xa9', '\x8e', '\xaa', + '\x8e', '\xab', '\x8e', '\xac', '\x8e', '\xad', '\x8e', '\xae', + '\x8e', '\xaf', '\x8e', '\xb0', '\x8e', '\xb1', '\x8e', '\xb2', + '\x8e', '\xb3', '\x8e', '\xb4', '\x8e', '\xb5', '\x8e', '\xb7', + '\x8e', '\xb8', '\x8e', '\xb9', '\x8e', '\xba', '\x8e', '\xbb', + '\x8e', '\xbd', '\x8e', '\xbe', '\x8e', '\xbf', '\x8f', '\x80', + '\x8f', '\x81', '\x8f', '\x82', '\x8f', '\x83', '\x8f', '\x84', + '\x8f', '\x86', '\x8f', '\x87', '\x8f', '\x88', '\x8f', '\x89', + '\x8f', '\x8a', '\x90', '\x80', '\x90', '\x81', '\x90', '\x82', + '\x90', '\x83', '\x90', '\x84', '\x90', '\x85', '\x90', '\x86', + '\x90', '\x87', '\x90', '\x88', '\x90', '\x89', '\x90', '\x8a', + '\x90', '\x8b', '\x90', '\x8c', '\x90', '\x8d', '\x90', '\x8e', + '\x90', '\x8f', '\x90', '\x90', '\x90', '\x91', '\x90', '\x92', + '\x90', '\x93', '\x90', '\x94', '\x90', '\x95', '\x90', '\x96', + '\x90', '\x97', '\x90', '\x98', '\x90', '\x99', '\x90', '\x9a', + '\x90', '\x9b', '\x90', '\x9c', '\x90', '\x9d', '\x90', '\x9e', + '\x90', '\x9f', '\x90', '\xa0', '\x90', '\xa1', '\x90', '\xa2', + '\x90', '\xa3', '\x90', '\xa4', '\x90', '\xa5', '\x90', '\xa6', + '\x90', '\xa7', '\x90', '\xa8', '\x90', '\xa9', '\x90', '\xaa', + '\x90', '\xab', '\x90', '\xac', '\x90', '\xad', '\x90', '\xae', + '\x90', '\xaf', '\x90', '\xb0', '\x90', '\xb1', '\x90', '\xb2', + '\x90', '\xb3', '\x90', '\xb4', '\x90', '\xb5', '\x90', '\xb6', + '\x90', '\xb7', '\x90', '\xb8', '\x90', '\xb9', '\x90', '\xba', + '\x90', '\xbb', '\x90', '\xbc', '\x90', '\xbd', '\x90', '\xbe', + '\x91', '\x80', '\x91', '\x82', '\x91', '\x83', '\x91', '\x84', + '\x91', '\x85', '\x91', '\x86', '\x91', '\x87', '\x91', '\x88', + '\x91', '\x89', '\x91', '\x8a', '\x91', '\x8b', '\x91', '\x8c', + '\x91', '\x8d', '\x91', '\x8e', '\x91', '\x8f', '\x91', '\x90', + '\x91', '\x91', '\x91', '\x92', '\x91', '\x93', '\x91', '\x94', + '\x91', '\x95', '\x91', '\x96', '\x91', '\x97', '\x91', '\x98', + '\x91', '\x99', '\x91', '\x9a', '\x91', '\x9b', '\x91', '\x9c', + '\x91', '\x9d', '\x91', '\x9e', '\x91', '\x9f', '\x91', '\xa0', + '\x91', '\xa1', '\x91', '\xa2', '\x91', '\xa3', '\x91', '\xa4', + '\x91', '\xa5', '\x91', '\xa6', '\x91', '\xa7', '\x91', '\xa8', + '\x91', '\xa9', '\x91', '\xaa', '\x91', '\xae', '\x91', '\xaf', + '\x91', '\xba', '\x91', '\xbb', '\x91', '\xbc', '\x91', '\xbd', + '\x91', '\xbe', '\x91', '\xbf', '\x92', '\x80', '\x92', '\x81', + '\x92', '\x82', '\x92', '\x83', '\x92', '\x84', '\x92', '\x85' + }; + int cols = core->print->cols; + if (cols < 1) { + cols = 1; + } + for (int i = 0; i < len; i += cols) { + rz_print_addr(core->print, core->offset + i); + for (int j = i; j < i + cols; j += 1) { + ut8 *p = (ut8 *)core->block + j; + if (j < len) { + rz_cons_printf("\xf0\x9f%c%c ", emoji[*p * 2], emoji[*p * 2 + 1]); + } else { + rz_cons_print(" "); + } + } + rz_cons_print(" "); + for (int j = i; j < len && j < i + cols; j += 1) { + ut8 *p = (ut8 *)core->block + j; + rz_print_byte(core->print, "%c", j, *p); + } + rz_cons_newline(); + } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_function_handler(RzCore *core, int argc, const char **argv) { + return RZ_CMD_STATUS_ERROR; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hexii_handler(RzCore *core, int argc, const char **argv) { + core->print->show_offset = rz_config_get_i(core->config, "hex.offset"); + rz_print_hexii(core->print, core->offset, core->block, + (int)core->blocksize, rz_config_get_i(core->config, "hex.cols")); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_common_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state, int wordsize) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + const char *query = argc > 2 ? argv[2] : NULL; + switch (wordsize) { + case 1: + case 2: + case 4: + case 8: + cmd_pxr(core, len, state, wordsize, query); + break; + default: + rz_warn_if_reached(); + return RZ_CMD_STATUS_ERROR; + } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + int wordsize = rz_analysis_get_address_bits(core->analysis) / 8; + return rz_print_hexword_references_common_handler(core, argc, argv, state, wordsize); +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_1_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexword_references_common_handler(core, argc, argv, state, 1); +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexword_references_common_handler(core, argc, argv, state, 2); +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexword_references_common_handler(core, argc, argv, state, 4); +} + +RZ_IPI RzCmdStatus rz_print_hexword_references_8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexword_references_common_handler(core, argc, argv, state, 8); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_sparse_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (!len) { + return RZ_CMD_STATUS_OK; + } + core->print->flags |= RZ_PRINT_FLAGS_SPARSE; + rz_core_print_hexdump(core, core->offset, core->block, len, 16, 1, 1); + core->print->flags &= (int)(((ut32)-1) & (~RZ_PRINT_FLAGS_SPARSE)); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_delta_pointer_table_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (!len) { + return RZ_CMD_STATUS_OK; + } + ut64 origin = argc > 2 ? rz_num_math(core->num, argv[2]) : core->offset; + // _pointer_table does rz_core_cmd with @, so it modifies core->block + // and this results in an UAF access when iterating over the jmptable + // so we do a new allocation to avoid that issue + ut8 *block = calloc(len, 1); + if (!block) { + return RZ_CMD_STATUS_ERROR; + } + memcpy(block, core->block, len); + _pointer_table(core, origin, core->offset, block, len, 4, state->mode); + free(block); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hexless_bytes_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + core->print->flags |= RZ_PRINT_FLAGS_NONHEX; + rz_core_print_hexdump(core, core->offset, + core->block, len, 8, 1, 1); + core->print->flags &= ~RZ_PRINT_FLAGS_NONHEX; + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hexless_words_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + if (!len) { + return RZ_CMD_STATUS_OK; + } + ut8 *buf = calloc(len, 4); + if (!buf) { + return RZ_CMD_STATUS_ERROR; + } + rz_io_read_at(core->io, core->offset, buf, len * 4); + core->print->flags |= RZ_PRINT_FLAGS_NONHEX; + rz_core_print_hexdump(core, core->offset, buf, len * 4, 8, 1, 1); + core->print->flags &= ~RZ_PRINT_FLAGS_NONHEX; + free(buf); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hexpair_bytes_handler(RzCore *core, int argc, const char **argv) { + int len = (int)rz_str_nlen((const char *)core->block, core->blocksize); + if (!len) { + return RZ_CMD_STATUS_OK; + } + rz_print_bytes(core->print, core->block, len, "%02x"); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_print_hexdump_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_hexdump_or_hexdiff(core, state->mode, core->offset, len, false)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_n_lines_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_hexdump_or_hexdiff(core, state->mode, core->offset, core->print->cols * len, false)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hex_common_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state, ut8 n) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_dump(core, state->mode, core->offset, n, len, RZ_CORE_PRINT_FORMAT_TYPE_HEXADECIMAL)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hex2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hex_common_handler(core, argc, argv, state, 2); +} +RZ_IPI RzCmdStatus rz_print_hexdump_hex4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hex_common_handler(core, argc, argv, state, 4); +} +RZ_IPI RzCmdStatus rz_print_hexdump_hex8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hex_common_handler(core, argc, argv, state, 8); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hexl_common_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state, ut8 n) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + bool hex_offset = rz_config_get_b(core->config, "hex.offset"); + bool quiet = state->mode == RZ_OUTPUT_MODE_QUIET || state->mode == RZ_OUTPUT_MODE_QUIETEST; + return bool2status(rz_core_print_hexdump_byline(core, !quiet && hex_offset, core->offset, len, n)); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_hex2l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hexl_common_handler(core, argc, argv, state, 2); +} +RZ_IPI RzCmdStatus rz_print_hexdump_hex4l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hexl_common_handler(core, argc, argv, state, 4); +} +RZ_IPI RzCmdStatus rz_print_hexdump_hex8l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { + return rz_print_hexdump_hexl_common_handler(core, argc, argv, state, 8); +} + +RZ_IPI RzCmdStatus rz_print_hexdump_oct_handler(RzCore *core, int argc, const char **argv) { + int len = argc > 1 ? (int)rz_num_math(core->num, argv[1]) : (int)core->blocksize; + return bool2status(rz_core_print_dump(core, RZ_OUTPUT_MODE_STANDARD, core->offset, 1, len, RZ_CORE_PRINT_FORMAT_TYPE_OCTAL)); +} + #define CMD_PRINT_BYTE_ARRAY_HANDLER_NORMAL(name, type) \ RZ_IPI RzCmdStatus name(RzCore *core, int argc, const char **argv) { \ char *code = rz_lang_byte_array(core->block, core->blocksize, type); \ diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index ab9412b47ed..0485de8bdcf 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -477,6 +477,34 @@ static const RzCmdDescArg print_utf16le_args[2]; static const RzCmdDescArg print_utf32le_args[2]; static const RzCmdDescArg print_utf16be_args[2]; static const RzCmdDescArg print_utf32be_args[2]; +static const RzCmdDescArg print_hexdump_args[2]; +static const RzCmdDescArg print_hexdump_annotated_args[2]; +static const RzCmdDescArg print_op_analysis_color_map_args[2]; +static const RzCmdDescArg print_hexdump_bits_args[2]; +static const RzCmdDescArg print_hexdump_comments_args[2]; +static const RzCmdDescArg print_hexdump_signed_integer_args[2]; +static const RzCmdDescArg print_hexdump_signed_integer2_args[2]; +static const RzCmdDescArg print_hexdump_signed_integer4_args[2]; +static const RzCmdDescArg print_hexdump_signed_integer8_args[2]; +static const RzCmdDescArg print_hexdump_emoji_args[2]; +static const RzCmdDescArg print_hexdump_function_args[2]; +static const RzCmdDescArg print_hexdump_hexii_args[2]; +static const RzCmdDescArg print_hexword_references_args[2]; +static const RzCmdDescArg print_hexword_references_1_args[2]; +static const RzCmdDescArg print_hexword_references_2_args[2]; +static const RzCmdDescArg print_hexword_references_4_args[2]; +static const RzCmdDescArg print_hexword_references_8_args[2]; +static const RzCmdDescArg print_hexdump_sparse_args[2]; +static const RzCmdDescArg print_hexdump_hexless_words_args[2]; +static const RzCmdDescArg print_hexdump_hexpair_bytes_args[2]; +static const RzCmdDescArg print_hexdump_hex2_args[2]; +static const RzCmdDescArg print_hexdump_hex2l_args[2]; +static const RzCmdDescArg print_hexdump_hex4_args[2]; +static const RzCmdDescArg print_hexdump_hex4l_args[2]; +static const RzCmdDescArg print_hexdump_hex8_args[2]; +static const RzCmdDescArg print_hexdump_hex8l_args[2]; +static const RzCmdDescArg print_hexdump_oct_args[2]; +static const RzCmdDescArg print_hexdump_n_lines_args[2]; static const RzCmdDescArg project_save_args[2]; static const RzCmdDescArg project_open_args[2]; static const RzCmdDescArg project_open_no_bin_io_args[2]; @@ -11184,6 +11212,451 @@ static const RzCmdDescHelp print_utf32be_help = { .args = print_utf32be_args, }; +static const RzCmdDescHelp px_help = { + .summary = "Show hexdump", +}; +static const RzCmdDescArg print_hexdump_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_help = { + .summary = "show hexdump", + .args = print_hexdump_args, +}; + +static const RzCmdDescArg print_hexdump_annotated_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_annotated_help = { + .summary = "show annotated hexdump", + .args = print_hexdump_annotated_args, +}; + +static const RzCmdDescArg print_op_analysis_color_map_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_op_analysis_color_map_help = { + .summary = "show op analysis color map", + .args = print_op_analysis_color_map_args, +}; + +static const RzCmdDescArg print_hexdump_bits_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_bits_help = { + .summary = "dump bits in hexdump form", + .args = print_hexdump_bits_args, +}; + +static const RzCmdDescArg print_hexdump_comments_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_comments_help = { + .summary = "show hexdump with comments", + .args = print_hexdump_comments_args, +}; + +static const RzCmdDescHelp pxd_help = { + .summary = "show signed integer dump", +}; +static const RzCmdDescArg print_hexdump_signed_integer_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_signed_integer_help = { + .summary = "show 1-byte integer dump", + .args = print_hexdump_signed_integer_args, +}; + +static const RzCmdDescArg print_hexdump_signed_integer2_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_signed_integer2_help = { + .summary = "show 2-bytes integer dump", + .args = print_hexdump_signed_integer2_args, +}; + +static const RzCmdDescArg print_hexdump_signed_integer4_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_signed_integer4_help = { + .summary = "show 4-bytes integer dump", + .args = print_hexdump_signed_integer4_args, +}; + +static const RzCmdDescArg print_hexdump_signed_integer8_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_signed_integer8_help = { + .summary = "show 8-bytes integer dump", + .args = print_hexdump_signed_integer8_args, +}; + +static const RzCmdDescArg print_hexdump_emoji_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_emoji_help = { + .summary = "emoji hexdump! :)", + .args = print_hexdump_emoji_args, +}; + +static const RzCmdDescArg print_hexdump_function_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_function_help = { + .summary = "show hexdump of current function", + .args = print_hexdump_function_args, +}; + +static const RzCmdDescArg print_hexdump_hexii_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hexii_help = { + .summary = "HexII compact binary representation", + .args = print_hexdump_hexii_args, +}; + +static const RzCmdDescHelp pxr_help = { + .summary = "show hexword references", +}; +static const RzCmdDescArg print_hexword_references_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexword_references_help = { + .summary = "show hexword references", + .args = print_hexword_references_args, +}; + +static const RzCmdDescArg print_hexword_references_1_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexword_references_1_help = { + .summary = "show hexword references", + .args = print_hexword_references_1_args, +}; + +static const RzCmdDescArg print_hexword_references_2_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexword_references_2_help = { + .summary = "show hexword references with hexdump", + .args = print_hexword_references_2_args, +}; + +static const RzCmdDescArg print_hexword_references_4_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexword_references_4_help = { + .summary = "show hexword references with hexdump", + .args = print_hexword_references_4_args, +}; + +static const RzCmdDescArg print_hexword_references_8_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexword_references_8_help = { + .summary = "show hexword references with hexdump", + .args = print_hexword_references_8_args, +}; + +static const RzCmdDescArg print_hexdump_sparse_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_sparse_help = { + .summary = "show hexadecimal in sparse mode", + .args = print_hexdump_sparse_args, +}; + +static const RzCmdDescArg print_delta_pointer_table_args[] = { + { 0 }, +}; +static const RzCmdDescHelp print_delta_pointer_table_help = { + .summary = "show delta pointer table in rizin commands", + .args = print_delta_pointer_table_args, +}; + +static const RzCmdDescArg print_hexdump_hexless_bytes_args[] = { + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hexless_bytes_help = { + .summary = "show bytes of hex-less hexdump", + .args = print_hexdump_hexless_bytes_args, +}; + +static const RzCmdDescArg print_hexdump_hexless_words_args[] = { + { + .name = "N", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hexless_words_help = { + .summary = "show words of hex-less hexdump", + .args = print_hexdump_hexless_words_args, +}; + +static const RzCmdDescArg print_hexdump_hexpair_bytes_args[] = { + { + .name = "N", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hexpair_bytes_help = { + .summary = "8bit hexpair list of bytes until zero byte", + .args = print_hexdump_hexpair_bytes_args, +}; + +static const RzCmdDescArg print_hexdump_hex2_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex2_help = { + .summary = "show 2-bytes hexadecimal integers dump", + .args = print_hexdump_hex2_args, +}; + +static const RzCmdDescArg print_hexdump_hex2l_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex2l_help = { + .summary = "show 2-bytes hexadecimal integers dump, one per line", + .args = print_hexdump_hex2l_args, +}; + +static const RzCmdDescArg print_hexdump_hex4_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex4_help = { + .summary = "show 4-bytes hexadecimal integers dump", + .args = print_hexdump_hex4_args, +}; + +static const RzCmdDescArg print_hexdump_hex4l_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex4l_help = { + .summary = "show 4-bytes hexadecimal integers dump, one per line", + .args = print_hexdump_hex4l_args, +}; + +static const RzCmdDescArg print_hexdump_hex8_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex8_help = { + .summary = "show 8-bytes hexadecimal integers dump", + .args = print_hexdump_hex8_args, +}; + +static const RzCmdDescArg print_hexdump_hex8l_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_hex8l_help = { + .summary = "show 8-bytes hexadecimal integers dump, one per line", + .args = print_hexdump_hex8l_args, +}; + +static const RzCmdDescArg print_hexdump_oct_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_oct_help = { + .summary = "show 1-byte octal integers dump", + .args = print_hexdump_oct_args, +}; + +static const RzCmdDescArg print_hexdump_n_lines_args[] = { + { + .name = "N", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp print_hexdump_n_lines_help = { + .summary = "display lines of hexdump", + .args = print_hexdump_n_lines_args, +}; + static const RzCmdDescHelp p6_help = { .summary = "Base64 decoding/encoding", }; @@ -16485,6 +16958,93 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *print_utf32be_cd = rz_cmd_desc_argv_modes_new(core->rcmd, cmd_print_cd, "psM", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_utf32be_handler, &print_utf32be_help); rz_warn_if_fail(print_utf32be_cd); + RzCmdDesc *px_cd = rz_cmd_desc_group_state_new(core->rcmd, cmd_print_cd, "px", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_handler, &print_hexdump_help, &px_help); + rz_warn_if_fail(px_cd); + RzCmdDesc *print_hexdump_annotated_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxa", rz_print_hexdump_annotated_handler, &print_hexdump_annotated_help); + rz_warn_if_fail(print_hexdump_annotated_cd); + + RzCmdDesc *print_op_analysis_color_map_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxA", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_LONG, rz_print_op_analysis_color_map_handler, &print_op_analysis_color_map_help); + rz_warn_if_fail(print_op_analysis_color_map_cd); + + RzCmdDesc *print_hexdump_bits_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxb", rz_print_hexdump_bits_handler, &print_hexdump_bits_help); + rz_warn_if_fail(print_hexdump_bits_cd); + + RzCmdDesc *print_hexdump_comments_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxc", rz_print_hexdump_comments_handler, &print_hexdump_comments_help); + rz_warn_if_fail(print_hexdump_comments_cd); + + RzCmdDesc *pxd_cd = rz_cmd_desc_group_state_new(core->rcmd, px_cd, "pxd", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_signed_integer_handler, &print_hexdump_signed_integer_help, &pxd_help); + rz_warn_if_fail(pxd_cd); + RzCmdDesc *print_hexdump_signed_integer2_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxd_cd, "pxdh", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_signed_integer2_handler, &print_hexdump_signed_integer2_help); + rz_warn_if_fail(print_hexdump_signed_integer2_cd); + + RzCmdDesc *print_hexdump_signed_integer4_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxd_cd, "pxdw", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_signed_integer4_handler, &print_hexdump_signed_integer4_help); + rz_warn_if_fail(print_hexdump_signed_integer4_cd); + + RzCmdDesc *print_hexdump_signed_integer8_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxd_cd, "pxdq", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_signed_integer8_handler, &print_hexdump_signed_integer8_help); + rz_warn_if_fail(print_hexdump_signed_integer8_cd); + + RzCmdDesc *print_hexdump_emoji_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxe", rz_print_hexdump_emoji_handler, &print_hexdump_emoji_help); + rz_warn_if_fail(print_hexdump_emoji_cd); + + RzCmdDesc *print_hexdump_function_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxf", rz_print_hexdump_function_handler, &print_hexdump_function_help); + rz_warn_if_fail(print_hexdump_function_cd); + + RzCmdDesc *print_hexdump_hexii_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxi", rz_print_hexdump_hexii_handler, &print_hexdump_hexii_help); + rz_warn_if_fail(print_hexdump_hexii_cd); + + RzCmdDesc *pxr_cd = rz_cmd_desc_group_state_new(core->rcmd, px_cd, "pxr", RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_RIZIN, rz_print_hexword_references_handler, &print_hexword_references_help, &pxr_help); + rz_warn_if_fail(pxr_cd); + RzCmdDesc *print_hexword_references_1_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxr_cd, "pxr1", RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_RIZIN, rz_print_hexword_references_1_handler, &print_hexword_references_1_help); + rz_warn_if_fail(print_hexword_references_1_cd); + + RzCmdDesc *print_hexword_references_2_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxr_cd, "pxr2", RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_RIZIN, rz_print_hexword_references_2_handler, &print_hexword_references_2_help); + rz_warn_if_fail(print_hexword_references_2_cd); + + RzCmdDesc *print_hexword_references_4_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxr_cd, "pxr4", RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_RIZIN, rz_print_hexword_references_4_handler, &print_hexword_references_4_help); + rz_warn_if_fail(print_hexword_references_4_cd); + + RzCmdDesc *print_hexword_references_8_cd = rz_cmd_desc_argv_state_new(core->rcmd, pxr_cd, "pxr8", RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_TABLE | RZ_OUTPUT_MODE_RIZIN, rz_print_hexword_references_8_handler, &print_hexword_references_8_help); + rz_warn_if_fail(print_hexword_references_8_cd); + + RzCmdDesc *print_hexdump_sparse_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxs", rz_print_hexdump_sparse_handler, &print_hexdump_sparse_help); + rz_warn_if_fail(print_hexdump_sparse_cd); + + RzCmdDesc *print_delta_pointer_table_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxt", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_delta_pointer_table_handler, &print_delta_pointer_table_help); + rz_warn_if_fail(print_delta_pointer_table_cd); + + RzCmdDesc *print_hexdump_hexless_bytes_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxx", rz_print_hexdump_hexless_bytes_handler, &print_hexdump_hexless_bytes_help); + rz_warn_if_fail(print_hexdump_hexless_bytes_cd); + + RzCmdDesc *print_hexdump_hexless_words_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxX", rz_print_hexdump_hexless_words_handler, &print_hexdump_hexless_words_help); + rz_warn_if_fail(print_hexdump_hexless_words_cd); + + RzCmdDesc *print_hexdump_hexpair_bytes_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "px0", rz_print_hexdump_hexpair_bytes_handler, &print_hexdump_hexpair_bytes_help); + rz_warn_if_fail(print_hexdump_hexpair_bytes_cd); + + RzCmdDesc *print_hexdump_hex2_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxh", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex2_handler, &print_hexdump_hex2_help); + rz_warn_if_fail(print_hexdump_hex2_cd); + + RzCmdDesc *print_hexdump_hex2l_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxH", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex2l_handler, &print_hexdump_hex2l_help); + rz_warn_if_fail(print_hexdump_hex2l_cd); + + RzCmdDesc *print_hexdump_hex4_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxw", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex4_handler, &print_hexdump_hex4_help); + rz_warn_if_fail(print_hexdump_hex4_cd); + + RzCmdDesc *print_hexdump_hex4l_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxW", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex4l_handler, &print_hexdump_hex4l_help); + rz_warn_if_fail(print_hexdump_hex4l_cd); + + RzCmdDesc *print_hexdump_hex8_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxq", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex8_handler, &print_hexdump_hex8_help); + rz_warn_if_fail(print_hexdump_hex8_cd); + + RzCmdDesc *print_hexdump_hex8l_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxQ", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_hex8l_handler, &print_hexdump_hex8l_help); + rz_warn_if_fail(print_hexdump_hex8l_cd); + + RzCmdDesc *print_hexdump_oct_cd = rz_cmd_desc_argv_new(core->rcmd, px_cd, "pxo", rz_print_hexdump_oct_handler, &print_hexdump_oct_help); + rz_warn_if_fail(print_hexdump_oct_cd); + + RzCmdDesc *print_hexdump_n_lines_cd = rz_cmd_desc_argv_state_new(core->rcmd, px_cd, "pxl", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_print_hexdump_n_lines_handler, &print_hexdump_n_lines_help); + rz_warn_if_fail(print_hexdump_n_lines_cd); + RzCmdDesc *p6_cd = rz_cmd_desc_group_new(core->rcmd, cmd_print_cd, "p6", NULL, NULL, &p6_help); rz_warn_if_fail(p6_cd); RzCmdDesc *cmd_base64_encode_cd = rz_cmd_desc_argv_modes_new(core->rcmd, p6_cd, "p6e", RZ_OUTPUT_MODE_STANDARD, rz_cmd_base64_encode_handler, &cmd_base64_encode_help); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 212debc85c0..e4793e14742 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -818,6 +818,36 @@ RZ_IPI RzCmdStatus rz_print_utf16le_handler(RzCore *core, int argc, const char * RZ_IPI RzCmdStatus rz_print_utf32le_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); RZ_IPI RzCmdStatus rz_print_utf16be_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); RZ_IPI RzCmdStatus rz_print_utf32be_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); +RZ_IPI RzCmdStatus rz_print_hexdump_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_annotated_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_op_analysis_color_map_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_bits_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_comments_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_signed_integer8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_emoji_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_function_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_hexii_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexword_references_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexword_references_1_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexword_references_2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexword_references_4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexword_references_8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_sparse_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_delta_pointer_table_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hexless_bytes_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_hexless_words_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_hexpair_bytes_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_hex2_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hex2l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hex4_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hex4l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hex8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_hex8l_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_print_hexdump_oct_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_print_hexdump_n_lines_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); RZ_IPI RzCmdStatus rz_cmd_base64_encode_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); RZ_IPI RzCmdStatus rz_cmd_base64_decode_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); RZ_IPI int rz_cmd_print(void *data, const char *input); diff --git a/librz/core/cmd_descs/cmd_print.yaml b/librz/core/cmd_descs/cmd_print.yaml index 86bee8f850a..9203addd169 100644 --- a/librz/core/cmd_descs/cmd_print.yaml +++ b/librz/core/cmd_descs/cmd_print.yaml @@ -496,6 +496,310 @@ commands: - name: type type: RZ_CMD_ARG_TYPE_NUM optional: true + - name: px + summary: Show hexdump + subcommands: + - name: px + summary: show hexdump + cname: print_hexdump + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxa + summary: show annotated hexdump + cname: print_hexdump_annotated + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxA + summary: show op analysis color map + cname: print_op_analysis_color_map + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_LONG + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxb + summary: dump bits in hexdump form + cname: print_hexdump_bits + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxc + summary: show hexdump with comments + cname: print_hexdump_comments + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxd + summary: show signed integer dump + subcommands: + - name: pxd + summary: show 1-byte integer dump + cname: print_hexdump_signed_integer + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxdh + summary: show 2-bytes integer dump + cname: print_hexdump_signed_integer2 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxdw + summary: show 4-bytes integer dump + cname: print_hexdump_signed_integer4 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxdq + summary: show 8-bytes integer dump + cname: print_hexdump_signed_integer8 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxe + summary: emoji hexdump! :) + cname: print_hexdump_emoji + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxf + summary: show hexdump of current function + cname: print_hexdump_function + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxi + summary: HexII compact binary representation + cname: print_hexdump_hexii + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxr + summary: show hexword references + subcommands: + - name: pxr + summary: show hexword references + cname: print_hexword_references + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_RIZIN + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxr1 + summary: show hexword references + cname: print_hexword_references_1 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_RIZIN + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxr2 + summary: show hexword references with hexdump + cname: print_hexword_references_2 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_RIZIN + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxr4 + summary: show hexword references with hexdump + cname: print_hexword_references_4 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_RIZIN + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxr8 + summary: show hexword references with hexdump + cname: print_hexword_references_8 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_QUIET + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + - RZ_OUTPUT_MODE_TABLE + - RZ_OUTPUT_MODE_RIZIN + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxs + summary: show hexadecimal in sparse mode + cname: print_hexdump_sparse + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxt + summary: show delta pointer table in rizin commands + cname: print_delta_pointer_table + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: [] + - name: pxx + summary: show bytes of hex-less hexdump + cname: print_hexdump_hexless_bytes + args: [] + - name: pxX + summary: show words of hex-less hexdump + cname: print_hexdump_hexless_words + args: + - name: N + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: px0 + summary: 8bit hexpair list of bytes until zero byte + cname: print_hexdump_hexpair_bytes + args: + - name: N + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxh + summary: show 2-bytes hexadecimal integers dump + cname: print_hexdump_hex2 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxH + summary: show 2-bytes hexadecimal integers dump, one per line + cname: print_hexdump_hex2l + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxw + summary: show 4-bytes hexadecimal integers dump + cname: print_hexdump_hex4 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxW + summary: show 4-bytes hexadecimal integers dump, one per line + cname: print_hexdump_hex4l + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxq + summary: show 8-bytes hexadecimal integers dump + cname: print_hexdump_hex8 + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxQ + summary: show 8-bytes hexadecimal integers dump, one per line + cname: print_hexdump_hex8l + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxo + summary: show 1-byte octal integers dump + cname: print_hexdump_oct + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true + - name: pxl + summary: display lines of hexdump + cname: print_hexdump_n_lines + type: RZ_CMD_DESC_TYPE_ARGV_STATE + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: + - name: N + type: RZ_CMD_ARG_TYPE_RZNUM + optional: true - name: p6 summary: Base64 decoding/encoding subcommands: diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 5e0ce609abc..1ce1df9f538 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -142,6 +142,12 @@ RZ_IPI void rz_core_asm_bb_middle(RZ_NONNULL RzCore *core, ut64 at, RZ_INOUT RZ_ RZ_IPI bool rz_core_handle_backwards_disasm(RZ_NONNULL RzCore *core, RZ_NONNULL RZ_INOUT int *pn_opcodes, RZ_NONNULL RZ_INOUT int *pn_bytes); +/* cprint.c */ +RZ_IPI bool rz_core_print_hexdump_diff(RZ_NONNULL RzCore *core, ut64 aa, ut64 ba, ut64 len); +RZ_IPI bool rz_core_print_dump(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, ut8 n, int len, RzCorePrintFormatType format); +RZ_IPI bool rz_core_print_hexdump_or_hexdiff(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, int len, bool use_comments); +RZ_IPI bool rz_core_print_hexdump_byline(RZ_NONNULL RzCore *core, bool hex_offset, ut64 addr, int len, ut8 size); + /* cmd_seek.c */ RZ_IPI bool rz_core_seek_to_register(RzCore *core, const char *input, bool is_silent); RZ_IPI int rz_core_seek_opcode_forward(RzCore *core, int n, bool silent); diff --git a/librz/core/cprint.c b/librz/core/cprint.c index de3d36d536b..caa7a0cd865 100644 --- a/librz/core/cprint.c +++ b/librz/core/cprint.c @@ -161,18 +161,315 @@ RZ_API RZ_OWN char *rz_core_esil_of_hex(RzCore *core, ut8 *hex, int len) { RZ_IPI void rz_core_print_hexdump(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz) { char *string = rz_print_hexdump_str(core->print, addr, buf, len, base, step, zoomsz); + if (!string) { + RZ_LOG_ERROR("fail to print hexdump at 0x%" PFMT64x "\n", addr); + return; + } rz_cons_print(string); free(string); } RZ_IPI void rz_core_print_jsondump(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, int wordsize) { char *string = rz_print_jsondump_str(core->print, buf, len, wordsize); + if (!string) { + RZ_LOG_ERROR("fail to print json hexdump\n"); + return; + } rz_cons_print(string); free(string); } RZ_IPI void rz_core_print_hexdiff(RZ_NONNULL RzCore *core, ut64 aa, RZ_NONNULL const ut8 *_a, ut64 ba, RZ_NONNULL const ut8 *_b, int len, int scndcol) { char *string = rz_print_hexdiff_str(core->print, aa, _a, ba, _b, len, scndcol); + if (!string) { + RZ_LOG_ERROR("fail to print hexdiff between 0x%" PFMT64x " and 0x%" PFMT64x "\n", aa, ba); + return; + } rz_cons_print(string); free(string); -} \ No newline at end of file +} + +/** + * \brief Print hexdump diff between \p aa and \p ba with \p len + */ +RZ_API char *rz_core_print_hexdump_diff_str(RZ_NONNULL RzCore *core, ut64 aa, ut64 ba, ut64 len) { + rz_return_val_if_fail(core && core->cons && len > 0, false); + ut8 *a = malloc(len); + if (!a) { + return NULL; + } + ut8 *b = malloc(len); + if (!b) { + free(a); + return NULL; + } + + RZ_LOG_VERBOSE("print hexdump diff 0x%" PFMT64x " 0x%" PFMT64x " with len:%" PFMT64d "\n", aa, ba, len); + + rz_io_read_at(core->io, aa, a, (int)len); + rz_io_read_at(core->io, ba, b, (int)len); + int col = core->cons->columns > 123; + char *pstr = rz_print_hexdiff_str(core->print, aa, a, + ba, b, (int)len, col); + free(a); + free(b); + return pstr; +} + +RZ_IPI bool rz_core_print_hexdump_diff(RZ_NONNULL RzCore *core, ut64 aa, ut64 ba, ut64 len) { + char *string = rz_core_print_hexdump_diff_str(core, aa, ba, len); + if (!string) { + RZ_LOG_ERROR("fail to print hexdump diff between 0x%" PFMT64x " and 0x%" PFMT64x "\n", aa, ba); + return false; + } + rz_cons_print(string); + free(string); + return true; +} + +static inline st8 format_type_to_base(const RzCorePrintFormatType format, const ut8 n) { + static const st8 bases[][9] = { + { 0, 8 }, + { 0, -1, -10, [4] = 10, [8] = -8 }, + { 0, 16, 32, [4] = 32, [8] = 64 }, + }; + if (format >= RZ_CORE_PRINT_FORMAT_TYPE_INVALID || n >= sizeof(bases[0])) { + return 0; + } + return bases[format][n]; +} + +static inline void fix_size_from_format(const RzCorePrintFormatType format, ut8 *size) { + if (format != RZ_CORE_PRINT_FORMAT_TYPE_INTEGER) { + return; + } + static const st8 sizes[] = { + 0, 4, 2, [4] = 4, [8] = 4 + }; + if (*size >= sizeof(sizes)) { + return; + } + *size = sizes[*size]; +} + +static inline void len_fixup(RzCore *core, ut64 *addr, int *len) { + if (!len) { + return; + } + bool is_positive = *len > 0; + if (RZ_ABS(*len) > core->blocksize_max) { + RZ_LOG_ERROR("this is too big (0x%" PFMT32x + " < 0x%" PFMT32x ").", + *len, core->blocksize_max); + *len = (int)core->blocksize_max; + } + if (is_positive) { + return; + } + *len = RZ_ABS(*len); + if (addr) { + *addr = *addr - *len; + } +} + +/** + * \brief Print dump at \p addr + * \param n Word size by bytes (1,2,4,8) + * \param len Dump bytes length + * \param format Print format, such as RZ_CORE_PRINT_FORMAT_TYPE_HEXADECIMAL + */ +RZ_API char *rz_core_print_dump_str(RZ_NONNULL RzCore *core, RzOutputMode mode, + ut64 addr, ut8 n, int len, RzCorePrintFormatType format) { + rz_return_val_if_fail(core, false); + if (!len) { + return NULL; + } + st8 base = format_type_to_base(format, n); + if (!base) { + return NULL; + } + len_fixup(core, &addr, &len); + ut8 *buffer = malloc(len); + if (!buffer) { + return NULL; + } + + char *string = NULL; + rz_io_read_at(core->io, addr, buffer, len); + RzPrint *print = core->print; + rz_print_init_rowoffsets(print); + bool old_use_comments = print->use_comments; + print->use_comments = false; + + switch (mode) { + case RZ_OUTPUT_MODE_JSON: + string = rz_print_jsondump_str(print, buffer, len, n * 8); + break; + case RZ_OUTPUT_MODE_STANDARD: + fix_size_from_format(format, &n); + string = rz_print_hexdump_str(print, addr, buffer, len, base, (int)n, 1); + break; + default: + rz_warn_if_reached(); + break; + } + + print->use_comments = old_use_comments; + free(buffer); + return string; +} + +RZ_IPI bool rz_core_print_dump(RZ_NONNULL RzCore *core, RzOutputMode mode, + ut64 addr, ut8 n, int len, RzCorePrintFormatType format) { + char *string = rz_core_print_dump_str(core, mode, addr, n, len, format); + if (!string) { + RZ_LOG_ERROR("fail to print dump at 0x%" PFMT64x "\n", addr); + return false; + } + rz_cons_print(string); + return true; +} + +/** + * \brief Print hexdump at \p addr, but maybe print hexdiff if (diff.from or diff.to), \see "el diff" + * \param len Dump bytes length + */ +RZ_API char *rz_core_print_hexdump_or_hexdiff_str(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, int len, + bool use_comment) { + rz_return_val_if_fail(core, false); + if (!len) { + return NULL; + } + + char *string = NULL; + RzPrint *print = core->print; + bool old_use_comments = print->use_comments; + print->use_comments = use_comment ? print->flags & RZ_PRINT_FLAGS_COMMENT : false; + switch (mode) { + case RZ_OUTPUT_MODE_STANDARD: { + ut64 from = rz_config_get_i(core->config, "diff.from"); + ut64 to = rz_config_get_i(core->config, "diff.to"); + if (from == to && !from) { + len_fixup(core, &addr, &len); + ut8 *buffer = malloc(len); + if (!buffer) { + return NULL; + } + rz_io_read_at(core->io, addr, buffer, len); + string = rz_print_hexdump_str(core->print, rz_core_pava(core, addr), buffer, len, 16, 1, 1); + free(buffer); + } else { + string = rz_core_print_hexdump_diff_str(core, addr, addr + to - from, len); + } + core->num->value = len; + break; + } + case RZ_OUTPUT_MODE_JSON: + string = rz_print_jsondump_str(core->print, core->block, len, 8); + break; + default: + rz_warn_if_reached(); + break; + } + print->use_comments = old_use_comments; + return string; +} + +RZ_IPI bool rz_core_print_hexdump_or_hexdiff(RZ_NONNULL RzCore *core, RZ_NULLABLE RzOutputMode mode, ut64 addr, int len, + bool use_comment) { + char *string = rz_core_print_hexdump_or_hexdiff_str(core, mode, addr, len, use_comment); + if (!string) { + RZ_LOG_ERROR("fail to print hexdump at 0x%" PFMT64x "\n", addr); + return false; + } + rz_cons_print(string); + return true; +} + +static inline char *ut64_to_hex(const ut64 x, const ut8 width) { + RzStrBuf *sb = rz_strbuf_new(NULL); + rz_strbuf_appendf(sb, "%" PFMT64x, x); + ut8 len = rz_strbuf_length(sb); + if (len < width) { + rz_strbuf_prepend(sb, rz_str_pad('0', width - len)); + } + rz_strbuf_prepend(sb, "0x"); + return rz_strbuf_drain(sb); +} + +/** + * \brief Hexdump at \p addr + * \param len Dump bytes length + * \param size Word size by bytes (1,2,4,8) + * \return Hexdump string + */ +RZ_API RZ_OWN char *rz_core_print_hexdump_byline_str(RZ_NONNULL RzCore *core, bool hex_offset, + ut64 addr, int len, ut8 size) { + rz_return_val_if_fail(core, false); + if (!len) { + return NULL; + } + len_fixup(core, &addr, &len); + ut8 *buffer = malloc(len); + if (!buffer) { + return NULL; + } + + rz_io_read_at(core->io, addr, buffer, len); + const int round_len = len - (len % size); + RzStrBuf *sb = rz_strbuf_new(NULL); + for (int i = 0; i < round_len; i += size) { + const char *a, *b; + char *fn; + RzPrint *p = core->print; + RzFlagItem *f; + ut64 v = rz_read_ble(buffer + i, p->big_endian, size * 8); + if (p->colorfor) { + a = p->colorfor(p->user, v, true); + if (a && *a) { + b = Color_RESET; + } else { + a = b = ""; + } + } else { + a = b = ""; + } + f = rz_flag_get_at(core->flags, v, true); + fn = NULL; + if (f) { + st64 delta = (st64)(v - f->offset); + if (delta >= 0 && delta < 8192) { + if (v == f->offset) { + fn = strdup(f->name); + } else { + fn = rz_str_newf("%s+%" PFMT64d, f->name, v - f->offset); + } + } + } + char *vstr = ut64_to_hex(v, size * 2); + if (vstr) { + if (hex_offset) { + rz_strbuf_append(sb, rz_print_section_str(core->print, addr + i)); + rz_strbuf_appendf(sb, "0x%08" PFMT64x " %s%s%s%s%s\n", + (ut64)addr + i, a, vstr, b, fn ? " " : "", fn ? fn : ""); + } else { + rz_strbuf_appendf(sb, "%s%s%s\n", a, vstr, b); + } + } + free(vstr); + free(fn); + } + free(buffer); + return rz_strbuf_drain(sb); +} + +RZ_IPI bool rz_core_print_hexdump_byline(RZ_NONNULL RzCore *core, bool hexoffset, ut64 addr, int len, ut8 size) { + char *string = rz_core_print_hexdump_byline_str(core, hexoffset, addr, len, size); + if (!string) { + RZ_LOG_ERROR("fail to print hexdump by line at 0x%" PFMT64x "\n", addr); + return false; + } + rz_cons_print(string); + free(string); + return true; +} diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 161708c3927..c67558804cd 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -463,7 +463,7 @@ RZ_API bool rz_core_plugin_init(RzCore *core); RZ_API bool rz_core_plugin_add(RzCore *core, RzCorePlugin *plugin); RZ_API bool rz_core_plugin_fini(RzCore *core); -//#define rz_core_ncast(x) (RzCore*)(size_t)(x) +// #define rz_core_ncast(x) (RzCore*)(size_t)(x) RZ_API RZ_OWN RzList /**/ *rz_core_theme_list(RZ_NONNULL RzCore *core); RZ_API char *rz_core_theme_get(RzCore *core); RZ_API bool rz_core_theme_load(RzCore *core, const char *name); @@ -1056,12 +1056,24 @@ RZ_API bool rz_core_meta_string_add(RzCore *core, ut64 addr, ut64 size, RzStrEnc RZ_API bool rz_core_meta_pascal_string_add(RzCore *core, ut64 addr, RzStrEnc encoding, RZ_NULLABLE const char *name); // cprint.c +typedef enum { + RZ_CORE_PRINT_FORMAT_TYPE_OCTAL = 0, + RZ_CORE_PRINT_FORMAT_TYPE_INTEGER, + RZ_CORE_PRINT_FORMAT_TYPE_HEXADECIMAL, + RZ_CORE_PRINT_FORMAT_TYPE_INVALID, +} RzCorePrintFormatType; + RZ_API RZ_OWN char *rz_core_print_string_c_cpp(RzCore *core); RZ_API RZ_OWN char *rz_core_hex_of_assembly(RzCore *core, const char *assembly); RZ_API RZ_OWN char *rz_core_esil_of_assembly(RzCore *core, const char *assembly); RZ_API RZ_OWN char *rz_core_assembly_of_hex(RzCore *core, ut8 *hex, int len); RZ_API RZ_OWN char *rz_core_esil_of_hex(RzCore *core, ut8 *hex, int len); +RZ_API RZ_OWN char *rz_core_print_hexdump_diff_str(RZ_NONNULL RzCore *core, ut64 aa, ut64 ba, ut64 len); +RZ_API RZ_OWN char *rz_core_print_dump_str(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, ut8 n, int len, RzCorePrintFormatType format); +RZ_API RZ_OWN char *rz_core_print_hexdump_or_hexdiff_str(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, int len, bool use_comment); +RZ_API RZ_OWN char *rz_core_print_hexdump_byline_str(RZ_NONNULL RzCore *core, bool hex_offset, ut64 addr, int len, ut8 size); + /* rtr */ RZ_API bool rz_core_rtr_init(RZ_NONNULL RzCore *core); RZ_API int rz_core_rtr_cmds(RzCore *core, const char *port); diff --git a/librz/include/rz_util/rz_print.h b/librz/include/rz_util/rz_print.h index b7d9cf7ffe5..ae400576eff 100644 --- a/librz/include/rz_util/rz_print.h +++ b/librz/include/rz_util/rz_print.h @@ -196,7 +196,7 @@ RZ_API RzPrint *rz_print_new(void); RZ_API RzPrint *rz_print_free(RzPrint *p); RZ_API void rz_print_set_flags(RzPrint *p, int _flags); RZ_API void rz_print_addr(RzPrint *p, ut64 addr); -RZ_API void rz_print_section(RzPrint *p, ut64 at); +RZ_API char *rz_print_section_str(RzPrint *p, ut64 at); RZ_API void rz_print_hexii(RzPrint *p, ut64 addr, const ut8 *buf, int len, int step); RZ_API RZ_OWN char *rz_print_hexdump_str(RZ_NONNULL RzPrint *p, ut64 addr, RZ_NONNULL const ut8 *buf, int len, int base, int step, size_t zoomsz); RZ_API RZ_OWN char *rz_print_jsondump_str(RZ_NONNULL RzPrint *p, RZ_NONNULL const ut8 *buf, int len, int wordsize); diff --git a/librz/util/print.c b/librz/util/print.c index b8293e618f4..8dc4b51d43b 100644 --- a/librz/util/print.c +++ b/librz/util/print.c @@ -508,14 +508,12 @@ static inline void print_section(RzStrBuf *sb, RzPrint *p, ut64 at) { rz_strbuf_appendf(sb, "%20s ", s); } -RZ_API void rz_print_section(RzPrint *p, ut64 at) { - rz_return_if_fail(p); +RZ_API char *rz_print_section_str(RzPrint *p, ut64 at) { + rz_return_val_if_fail(p, NULL); RzStrBuf sb; rz_strbuf_init(&sb); print_section(&sb, p, at); - char *s = rz_strbuf_drain_nofree(&sb); - p->cb_printf("%s", s); - free(s); + return rz_strbuf_drain_nofree(&sb); } static inline void print_cursor_l(RzStrBuf *sb, RzPrint *p, int cur, int len) { diff --git a/test/db/cmd/cmd_0 b/test/db/cmd/cmd_0 index 7ff9ae28428..580a16ef31d 100644 --- a/test/db/cmd/cmd_0 +++ b/test/db/cmd/cmd_0 @@ -98,23 +98,23 @@ EXPECT=<