diff --git a/librz/core/cmd/cmd_cmp.c b/librz/core/cmd/cmd_cmp.c index ac9d8652a6..40a6b42f55 100644 --- a/librz/core/cmd/cmd_cmp.c +++ b/librz/core/cmd/cmd_cmp.c @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include "../core_private.h" static int rizin_compare_words(RzCore *core, ut64 of, ut64 od, int len, int ws) { int i; @@ -54,12 +55,12 @@ static bool rizin_compare_unified(RzCore *core, RzCompareData *cmp) { min = RZ_MIN(16, (cmp->len - i)); if (!memcmp(cmp->data1 + i, cmp->data2 + i, min)) { rz_cons_printf(" "); - rz_print_hexdiff(core->print, cmp->addr1 + i, cmp->data1 + i, cmp->addr1 + i, cmp->data1 + i, min, 0); + rz_core_print_hexdiff(core, cmp->addr1 + i, cmp->data1 + i, cmp->addr1 + i, cmp->data1 + i, min, 0); } else { rz_cons_printf("- "); - rz_print_hexdiff(core->print, cmp->addr1 + i, cmp->data1 + i, cmp->addr2 + i, cmp->data2 + i, min, 0); + rz_core_print_hexdiff(core, cmp->addr1 + i, cmp->data1 + i, cmp->addr2 + i, cmp->data2 + i, min, 0); rz_cons_printf("+ "); - rz_print_hexdiff(core->print, cmp->addr2 + i, cmp->data2 + i, cmp->addr1 + i, cmp->data1 + i, min, 0); + rz_core_print_hexdiff(core, cmp->addr2 + i, cmp->data2 + i, cmp->addr1 + i, cmp->data1 + i, min, 0); } } if (headers) { @@ -183,7 +184,7 @@ RZ_IPI RzCmdStatus rz_cmd_cmp_hex_block_handler(RzCore *core, int argc, const ch if (b) { memset(b, 0xff, core->blocksize); rz_io_nread_at(core->io, addr, b, core->blocksize); - rz_print_hexdiff(core->print, core->offset, core->block, addr, b, core->blocksize, col); + rz_core_print_hexdiff(core, core->offset, core->block, addr, b, core->blocksize, col); } free(b); return RZ_CMD_STATUS_OK; @@ -199,7 +200,7 @@ RZ_IPI RzCmdStatus rz_cmd_cmp_hex_diff_lines_handler(RzCore *core, int argc, con if (b) { memset(b, 0xff, core->blocksize); rz_io_nread_at(core->io, addr, b, core->blocksize); - rz_print_hexdiff(core->print, core->offset, core->block, addr, b, core->blocksize, col); + rz_core_print_hexdiff(core, core->offset, core->block, addr, b, core->blocksize, col); } free(b); core->print->flags = oflags; diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index 890b95d741..5a3d34db4e 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -2189,7 +2189,7 @@ RZ_API void rz_core_print_cmp(RzCore *core, ut64 from, ut64 to) { memset(b, 0xff, core->blocksize); delta = addr - from; rz_io_read_at(core->io, to + delta, b, core->blocksize); - rz_print_hexdiff(core->print, core->offset, core->block, + rz_core_print_hexdiff(core, core->offset, core->block, to + delta, b, core->blocksize, col); free(b); } @@ -5576,7 +5576,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { rz_cons_break_push(NULL, NULL); switch (input[1]) { case 'j': // "pxj" - rz_print_jsondump(core->print, core->block, core->blocksize, 8); + rz_core_print_jsondump(core, core->block, core->blocksize, 8); break; case '/': // "px/" rz_core_print_examine(core, input + 2); @@ -5721,7 +5721,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case '1': // 1 byte signed words (byte) if (input[3] == 'j') { - rz_print_jsondump(core->print, core->block, + rz_core_print_jsondump(core, core->block, len, 8); } else { rz_core_print_hexdump(core, core->offset, @@ -5731,7 +5731,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case '2': // 2 byte signed words (short) if (input[3] == 'j') { - rz_print_jsondump(core->print, core->block, + rz_core_print_jsondump(core, core->block, len, 16); } else { rz_core_print_hexdump(core, core->offset, @@ -5740,7 +5740,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { break; case '8': if (input[3] == 'j') { - rz_print_jsondump(core->print, core->block, + rz_core_print_jsondump(core, core->block, len, 64); } else { rz_core_print_hexdump(core, core->offset, @@ -5753,7 +5753,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case 0: // 4 byte signed words if (input[2] == 'j' || (input[2] && input[3] == 'j')) { - rz_print_jsondump(core->print, core->block, + rz_core_print_jsondump(core, core->block, len, 32); } else { rz_core_print_hexdump(core, core->offset, @@ -5769,7 +5769,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case 'w': // "pxw" if (l != 0) { if (input[2] == 'j') { - rz_print_jsondump(core->print, core->block, len, 32); + rz_core_print_jsondump(core, core->block, len, 32); } else { rz_core_print_hexdump(core, core->offset, core->block, len, 32, 4, 1); } @@ -5849,7 +5849,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case 'h': // "pxh" if (l) { if (input[2] == 'j') { - rz_print_jsondump(core->print, core->block, len, 16); + rz_core_print_jsondump(core, core->block, len, 16); } else { rz_core_print_hexdump(core, core->offset, core->block, len, 32, 2, 1); @@ -5896,7 +5896,7 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) { case 'q': // "pxq" if (l) { if (input[2] == 'j') { - rz_print_jsondump(core->print, core->block, len, 64); + rz_core_print_jsondump(core, core->block, len, 64); } else { rz_core_print_hexdump(core, core->offset, core->block, len, 64, 8, 1); } diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 11ab24f624..f5bee248b7 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -186,6 +186,8 @@ RZ_IPI RzCmdStatus rz_regs_prev_handler(RzCore *core, RzReg *reg, int argc, cons RZ_IPI RzCmdStatus rz_regs_fpu_handler(RzCore *core, RzReg *reg, RzCmdRegSync sync_cb, int argc, const char **argv); 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); +RZ_IPI void rz_core_print_jsondump(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, int wordsize); +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); #if __WINDOWS__ /* windows_heap.c */ diff --git a/librz/core/cprint.c b/librz/core/cprint.c index b1206c5383..de3d36d536 100644 --- a/librz/core/cprint.c +++ b/librz/core/cprint.c @@ -164,3 +164,15 @@ RZ_IPI void rz_core_print_hexdump(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL 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); + 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); + rz_cons_print(string); + free(string); +} \ No newline at end of file diff --git a/librz/include/rz_util/rz_print.h b/librz/include/rz_util/rz_print.h index 28f7a41159..b7d9cf7ffe 100644 --- a/librz/include/rz_util/rz_print.h +++ b/librz/include/rz_util/rz_print.h @@ -199,8 +199,8 @@ RZ_API void rz_print_addr(RzPrint *p, ut64 addr); RZ_API void rz_print_section(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 int rz_print_jsondump(RzPrint *p, const ut8 *buf, int len, int wordsize); -RZ_API void rz_print_hexdiff(RzPrint *p, ut64 aa, const ut8 *a, ut64 ba, const ut8 *b, int len, int scndcol); +RZ_API RZ_OWN char *rz_print_jsondump_str(RZ_NONNULL RzPrint *p, RZ_NONNULL const ut8 *buf, int len, int wordsize); +RZ_API RZ_OWN char *rz_print_hexdiff_str(RZ_NONNULL RzPrint *p, ut64 aa, RZ_NONNULL const ut8 *_a, ut64 ba, RZ_NONNULL const ut8 *_b, int len, int scndcol); RZ_API void rz_print_bytes(RzPrint *p, const ut8 *buf, int len, const char *fmt); RZ_API void rz_print_fill(RzPrint *p, const ut8 *arr, int size, ut64 addr, int step); RZ_API void rz_print_byte(RzPrint *p, const char *fmt, int idx, ut8 ch); diff --git a/librz/util/print.c b/librz/util/print.c index a2c21eddcd..75d9e10e89 100644 --- a/librz/util/print.c +++ b/librz/util/print.c @@ -1159,19 +1159,33 @@ static ut8 *M(const ut8 *b, int len) { return r; } +/** + * \brief Print hexdump diff between \p _a and \p _b. + * \param p RzPrint instance. + * \param aa Address of first buffer. + * \param _a First buffer. + * \param ba Address of second buffer. + * \param _b Second buffer. + * \param len Diff length. + * \param scndcol True If core->cons->columns > 123 ? + * \return Hexdump diff string. + */ // TODO: add support for cursor -RZ_API void rz_print_hexdiff(RzPrint *p, ut64 aa, const ut8 *_a, ut64 ba, const ut8 *_b, int len, int scndcol) { +RZ_API RZ_OWN char *rz_print_hexdiff_str(RZ_NONNULL RzPrint *p, ut64 aa, RZ_NONNULL const ut8 *_a, + ut64 ba, RZ_NONNULL const ut8 *_b, int len, int scndcol) { + rz_return_val_if_fail(p && _a && _b && len > 0, NULL); ut8 *a, *b; char linediff, fmt[64]; int color = p->flags & RZ_PRINT_FLAGS_COLOR; int diffskip = p->flags & RZ_PRINT_FLAGS_DIFFOUT; int i, j, min; + RzStrBuf *sb = rz_strbuf_new(NULL); if (!((a = M(_a, len)))) { - return; + return NULL; } if (!((b = M(_b, len)))) { free(a); - return; + return NULL; } for (i = 0; i < len; i += 16) { min = RZ_MIN(16, len - i); @@ -1179,42 +1193,43 @@ RZ_API void rz_print_hexdiff(RzPrint *p, ut64 aa, const ut8 *_a, ut64 ba, const if (diffskip && linediff == '|') { continue; } - p->cb_printf("0x%08" PFMT64x " ", aa + i); + rz_strbuf_appendf(sb, "0x%08" PFMT64x " ", aa + i); for (j = 0; j < min; j++) { *fmt = color; - rz_print_cursor(p, i + j, 1, 1); - p->cb_printf("%s", BD(a, b)); - rz_print_cursor(p, i + j, 1, 0); + print_cursor_l(sb, p, i + j, 1); + rz_strbuf_appendf(sb, "%s", BD(a, b)); + print_cursor_r(sb, p, i + j, 1); } - p->cb_printf(" "); + rz_strbuf_append(sb, " "); for (j = 0; j < min; j++) { *fmt = color; - rz_print_cursor(p, i + j, 1, 1); - p->cb_printf("%s", CD(a, b)); - rz_print_cursor(p, i + j, 1, 0); + print_cursor_l(sb, p, i + j, 1); + rz_strbuf_appendf(sb, "%s", CD(a, b)); + print_cursor_r(sb, p, i + j, 1); } if (scndcol) { - p->cb_printf(" %c 0x%08" PFMT64x " ", linediff, ba + i); + rz_strbuf_appendf(sb, " %c 0x%08" PFMT64x " ", linediff, ba + i); for (j = 0; j < min; j++) { *fmt = color; - rz_print_cursor(p, i + j, 1, 1); - p->cb_printf("%s", BD(b, a)); - rz_print_cursor(p, i + j, 1, 0); + print_cursor_r(sb, p, i + j, 1); + rz_strbuf_appendf(sb, "%s", BD(b, a)); + print_cursor_r(sb, p, i + j, 1); } - p->cb_printf(" "); + rz_strbuf_append(sb, " "); for (j = 0; j < min; j++) { *fmt = color; - rz_print_cursor(p, i + j, 1, 1); - p->cb_printf("%s", CD(b, a)); - rz_print_cursor(p, i + j, 1, 0); + print_cursor_r(sb, p, i + j, 1); + rz_strbuf_appendf(sb, "%s", CD(b, a)); + print_cursor_r(sb, p, i + j, 1); } - p->cb_printf("\n"); + rz_strbuf_append(sb, "\n"); } else { - p->cb_printf(" %c\n", linediff); + rz_strbuf_appendf(sb, " %c\n", linediff); } } free(a); free(b); + return rz_strbuf_drain(sb); } RZ_API void rz_print_bytes(RzPrint *p, const ut8 *buf, int len, const char *fmt) { @@ -1559,45 +1574,33 @@ RZ_API int rz_print_get_cursor(RzPrint *p) { return p->cur_enabled ? p->cur : 0; } -RZ_API int rz_print_jsondump(RzPrint *p, const ut8 *buf, int len, int wordsize) { - ut16 *buf16 = (ut16 *)buf; - ut32 *buf32 = (ut32 *)buf; - ut64 *buf64 = (ut64 *)buf; - // TODDO: support p==NULL too - if (!p || !buf || len < 1 || wordsize < 1) { - return 0; - } +/** + * \brief Print dump in json format + * \param p RzPrint instance + * \param buf Buffer to print to + * \param len Print only this many bytes + * \param wordsize Size of a word in bits + * \return Dump JSON string + */ +RZ_API char *rz_print_jsondump_str(RZ_NONNULL RzPrint *p, RZ_NONNULL const ut8 *buf, int len, int wordsize) { + rz_return_val_if_fail(p && buf && len > 0 && wordsize > 0, 0); int bytesize = wordsize / 8; if (bytesize < 1) { bytesize = 8; } - int i, words = (len / bytesize); - p->cb_printf("["); - for (i = 0; i < words; i++) { - switch (wordsize) { - case 8: { - p->cb_printf("%s%d", i ? "," : "", buf[i]); - break; - } - case 16: { - ut16 w16 = rz_read_ble16(&buf16[i], p->big_endian); - p->cb_printf("%s%hd", i ? "," : "", w16); - break; - } - case 32: { - ut32 w32 = rz_read_ble32(&buf32[i], p->big_endian); - p->cb_printf("%s%d", i ? "," : "", w32); - break; - } - case 64: { - ut64 w64 = rz_read_ble64(&buf64[i], p->big_endian); - p->cb_printf("%s%" PFMT64d, i ? "," : "", w64); - break; - } - } + PJ *j = pj_new(); + if (!j) { + return NULL; } - p->cb_printf("]\n"); - return words; + pj_a(j); + for (int i = 0; i + bytesize < len; i += bytesize) { + ut64 word = rz_read_ble(buf + i, p->big_endian, wordsize); + pj_n(j, word); + } + pj_end(j); + char *str = strdup(pj_string(j)); + pj_free(j); + return str; } /**