diff --git a/librz/core/cautocmpl.c b/librz/core/cautocmpl.c index 61ef6e5bd6..646df30f59 100644 --- a/librz/core/cautocmpl.c +++ b/librz/core/cautocmpl.c @@ -536,13 +536,13 @@ static void autocmplt_cmd_arg_zign_space(RzCore *core, RzLineNSCompletionResult static void autocmplt_cmd_arg_choices(RzCore *core, RzLineNSCompletionResult *res, const char *s, size_t len, const RzCmdDescArg *arg) { char **oc, **c; oc = c = arg->choices_cb ? arg->choices_cb(core) : (char **)arg->choices; - for (c = oc; *c; c++) { + for (c = oc; c && *c; c++) { if (!strncmp(*c, s, len)) { rz_line_ns_completion_result_add(res, *c); } } if (arg->choices_cb) { - for (c = oc; *c; c++) { + for (c = oc; c && *c; c++) { free(*c); } free(oc); diff --git a/librz/core/cio.c b/librz/core/cio.c index 3cc07512f8..8c581d8280 100644 --- a/librz/core/cio.c +++ b/librz/core/cio.c @@ -92,221 +92,6 @@ RZ_API bool rz_core_dump(RzCore *core, const char *file, ut64 addr, ut64 size, i return true; } -static bool __endian_swap(ut8 *buf, ut32 blocksize, ut8 len) { - ut32 i; - ut16 v16; - ut32 v32; - ut64 v64; - if (len != 8 && len != 4 && len != 2 && len != 1) { - eprintf("Invalid word size. Use 1, 2, 4 or 8\n"); - return false; - } - if (len == 1) { - return true; - } - for (i = 0; i < blocksize; i += len) { - switch (len) { - case 8: - v64 = rz_read_at_be64(buf, i); - rz_write_at_le64(buf, v64, i); - break; - case 4: - v32 = rz_read_at_be32(buf, i); - rz_write_at_le32(buf, v32, i); - break; - case 2: - v16 = rz_read_at_be16(buf, i); - rz_write_at_le16(buf, v16, i); - break; - } - } - return true; -} - -RZ_API ut8 *rz_core_transform_op(RzCore *core, const char *arg, char op) { - int i, j; - ut64 len; - char *str = NULL; - ut8 *buf; - - buf = (ut8 *)malloc(core->blocksize); - if (!buf) { - return NULL; - } - memcpy(buf, core->block, core->blocksize); - - if (op != 'e') { - // fill key buffer either from arg or from clipboard - if (arg) { // parse arg for key - // rz_hex_str2bin() is guaranteed to output maximum half the - // input size, or 1 byte if there is just a single nibble. - str = (char *)malloc(strlen(arg) / 2 + 1); - if (!str) { - goto beach; - } - len = rz_hex_str2bin(arg, (ut8 *)str); - // Output is invalid if there was just a single nibble, - // but in that case, len is negative (-1). - if (len <= 0) { - eprintf("Invalid hexpair string\n"); - goto beach; - } - } else { // use clipboard as key - const ut8 *tmp = rz_buf_data(core->yank_buf, &len); - str = rz_mem_dup(tmp, len); - if (!str) { - goto beach; - } - } - } else { - len = 0; - } - - // execute the operand - if (op == 'e') { - int wordsize = 1; - char *os, *p, *s = strdup(arg); - int n = 0, from = 0, to = UT8_MAX, dif = 0, step = 1; - os = s; - p = strchr(s, ' '); - if (p) { - *p = 0; - from = rz_num_math(core->num, s); - s = p + 1; - } - p = strchr(s, ' '); - if (p) { - *p = 0; - to = rz_num_math(core->num, s); - s = p + 1; - } - p = strchr(s, ' '); - if (p) { - *p = 0; - step = rz_num_math(core->num, s); - s = p + 1; - wordsize = rz_num_math(core->num, s); - } else { - step = rz_num_math(core->num, s); - } - free(os); - eprintf("from %d to %d step %d size %d\n", from, to, step, wordsize); - dif = (to <= from) ? UT8_MAX : to - from + 1; - if (wordsize == 1) { - from %= (UT8_MAX + 1); - } - if (dif < 1) { - dif = UT8_MAX + 1; - } - if (step < 1) { - step = 1; - } - if (wordsize < 1) { - wordsize = 1; - } - if (wordsize == 1) { - for (i = n = 0; i < core->blocksize; i++, n += step) { - buf[i] = (ut8)(n % dif) + from; - } - } else if (wordsize == 2) { - ut16 num16 = from; - for (i = 0; i < core->blocksize; i += wordsize, num16 += step) { - rz_write_le16(buf + i, num16); - } - } else if (wordsize == 4) { - ut32 num32 = from; - for (i = 0; i < core->blocksize; i += wordsize, num32 += step) { - rz_write_le32(buf + i, num32); - } - } else if (wordsize == 8) { - ut64 num64 = from; - for (i = 0; i < core->blocksize; i += wordsize, num64 += step) { - rz_write_le64(buf + i, num64); - } - } else { - eprintf("Invalid word size. Use 1, 2, 4 or 8\n"); - } - } else if (op == '2' || op == '4' || op == '8') { // "wo2" "wo4" "wo8" - int inc = op - '0'; - ut8 tmp; - for (i = 0; (i + inc) <= core->blocksize; i += inc) { - if (inc == 2) { - tmp = buf[i]; - buf[i] = buf[i + 1]; - buf[i + 1] = tmp; - } else if (inc == 4) { - tmp = buf[i]; - buf[i] = buf[i + 3]; - buf[i + 3] = tmp; - tmp = buf[i + 1]; - buf[i + 1] = buf[i + 2]; - buf[i + 2] = tmp; - } else if (inc == 8) { - tmp = buf[i]; - buf[i] = buf[i + 7]; - buf[i + 7] = tmp; - - tmp = buf[i + 1]; - buf[i + 1] = buf[i + 6]; - buf[i + 6] = tmp; - - tmp = buf[i + 2]; - buf[i + 2] = buf[i + 5]; - buf[i + 5] = tmp; - - tmp = buf[i + 3]; - buf[i + 3] = buf[i + 4]; - buf[i + 4] = tmp; - } else { - eprintf("Invalid inc, use 2, 4 or 8.\n"); - break; - } - } - } else { - bool be = rz_config_get_i(core->config, "cfg.bigendian"); - if (!be) { - if (!__endian_swap((ut8 *)str, len, len)) { - goto beach; - } - } - for (i = j = 0; i < core->blocksize; i++) { - switch (op) { - case 'x': buf[i] ^= str[j]; break; - case 'a': buf[i] += str[j]; break; - case 's': buf[i] -= str[j]; break; - case 'm': buf[i] *= str[j]; break; - case 'w': buf[i] = str[j]; break; - case 'd': buf[i] = (str[j]) ? (buf[i] / str[j]) : 0; break; - case 'r': buf[i] >>= str[j]; break; - case 'l': buf[i] <<= str[j]; break; - case 'o': buf[i] |= str[j]; break; - case 'A': buf[i] &= str[j]; break; - } - j++; - if (j >= len) { - j = 0; /* cyclic key */ - } - } - } - - free(str); - return buf; -beach: - free(str); - free(buf); - return NULL; -} - -RZ_API int rz_core_write_op(RzCore *core, const char *arg, char op) { - ut8 *buf = rz_core_transform_op(core, arg, op); - if (!buf) { - return false; - } - int ret = rz_core_write_at(core, core->offset, buf, core->blocksize); - free(buf); - return ret; -} - // Get address-specific bits and arch at a certain address. // If there are no specific infos (i.e. asm.bits and asm.arch should apply), the bits and arch will be 0 or NULL respectively! RZ_API void rz_core_arch_bits_at(RzCore *core, ut64 addr, RZ_OUT RZ_NULLABLE int *bits, RZ_OUT RZ_BORROW RZ_NULLABLE const char **arch) { @@ -366,6 +151,9 @@ RZ_API bool rz_core_write_at(RzCore *core, ut64 addr, const ut8 *buf, int size) if (addr >= core->offset && addr <= core->offset + core->blocksize - 1) { rz_core_block_read(core); } + if (rz_config_get_i(core->config, "cfg.wseek")) { + rz_core_seek_delta(core, size, true); + } return ret; } @@ -492,9 +280,6 @@ RZ_API int rz_core_write_hexpair(RzCore *core, ut64 addr, const char *pairs) { RZ_LOG_ERROR("Could not write hexpair '%s' at %" PFMT64x "\n", pairs, addr); goto err; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } err: free(buf); return len; @@ -525,9 +310,6 @@ RZ_API bool rz_core_write_block(RzCore *core, ut64 addr, ut8 *data, size_t len) RZ_LOG_ERROR("Could not write cyclic data (%d bytes) at %" PFMT64x "\n", core->blocksize, addr); goto err; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, core->blocksize, true); - } res = true; err: free(buf); @@ -563,10 +345,6 @@ RZ_API int rz_core_write_assembly(RzCore *core, ut64 addr, const char *instructi goto err; } ret = acode->len; - - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, ret, true); - } err: rz_asm_code_free(acode); return ret; @@ -616,10 +394,6 @@ RZ_API int rz_core_write_assembly_fill(RzCore *core, ut64 addr, const char *inst goto err; } ret = acode->len; - - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, ret, true); - } err: rz_asm_code_free(acode); return ret; @@ -761,10 +535,6 @@ RZ_API bool rz_core_write_value_at(RzCore *core, ut64 addr, ut64 value, int sz) core->num->value = 1; return false; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, sz, true); - } - return true; } @@ -822,10 +592,6 @@ RZ_API bool rz_core_write_value_inc_at(RzCore *core, ut64 addr, st64 value, int RZ_LOG_ERROR("Could not write %d bytes at %" PFMT64x "\n", sz, addr); return false; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, sz, true); - } - return true; } @@ -850,13 +616,52 @@ RZ_API bool rz_core_write_string_at(RzCore *core, ut64 addr, const char *s) { free(str); return false; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } free(str); return true; } +/** + * \brief Write a given string \p s as a wide string at the specified \p addr + * + * \param core RzCore reference + * \param addr Address where to write the string + * \param s String to write. The string is unescaped, meaning that if there is `\n` it becomes 0x0a + */ +RZ_API bool rz_core_write_string_wide_at(RzCore *core, ut64 addr, const char *s) { + rz_return_val_if_fail(core && s, false); + + bool res = false; + char *str = strdup(s); + if (!str) { + return false; + } + + int len = rz_str_unescape(str); + if (len < 1) { + goto str_err; + } + + len++; // Consider for the terminator char + char *tmp = RZ_NEWS(char, len * 2); + if (!tmp) { + goto str_err; + } + + for (int i = 0; i < len; i++) { + tmp[i * 2] = str[i]; + tmp[i * 2 + 1] = 0; + } + + if (!rz_core_write_at(core, addr, (const ut8 *)tmp, len * 2)) { + RZ_LOG_ERROR("Could not write wide string '%s' at %" PFMT64x "\n", s, addr); + free(str); + return false; + } + res = true; +str_err: + free(str); + return res; +} /** * \brief Write at the specified \p addr the length of the string in one byte, * followed by the given string \p s @@ -881,9 +686,6 @@ RZ_API bool rz_core_write_length_string_at(RzCore *core, ut64 addr, const char * free(str); return false; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } free(str); return true; } @@ -927,11 +729,7 @@ RZ_API bool rz_core_write_base64_at(RzCore *core, ut64 addr, const char *s) { RZ_LOG_ERROR("Could not write base64 encoded string '%s' at %" PFMT64x "\n", s, addr); goto err; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } res = true; - err: free(buf); return res; @@ -959,11 +757,7 @@ RZ_API bool rz_core_write_base64d_at(RzCore *core, ut64 addr, const char *s) { RZ_LOG_ERROR("Could not write base64 decoded string '%s' at %" PFMT64x "\n", s, addr); goto err; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } res = true; - err: free(buf); return res; @@ -994,11 +788,7 @@ RZ_API bool rz_core_write_random_at(RzCore *core, ut64 addr, size_t len) { RZ_LOG_ERROR("Could not write random data of length %zd at %" PFMT64x "\n", len, addr); goto err; } - if (rz_config_get_i(core->config, "cfg.wseek")) { - rz_core_seek_delta(core, len, true); - } res = true; - err: free(buf); return res; @@ -1104,3 +894,202 @@ RZ_API RzCmdStatus rz_core_io_pcache_print(RzCore *core, RzIODesc *desc, RzCmdSt rz_list_free(caches); return RZ_CMD_STATUS_OK; } + +/** + * \brief Write a given string \p s, followed by the zero terminator, at the specified \p addr + * + * \param core RzCore reference + * \param addr Address where to write the string + * \param s String to write. The string is unescaped, meaning that if there is `\n` it becomes 0x0a + */ +RZ_API bool rz_core_write_string_zero_at(RzCore *core, ut64 addr, const char *s) { + rz_return_val_if_fail(core && s, false); + + char *str = strdup(s); + if (!str) { + return false; + } + + int len = rz_str_unescape(str); + if (!rz_core_write_at(core, addr, (const ut8 *)str, len + 1)) { + RZ_LOG_ERROR("Could not write '%s' at %" PFMT64x "\n", s, addr); + free(str); + return false; + } + free(str); + return true; +} + +/** + * \brief Transform a block of data at \p addr according to the operation \p op and the hexvalue \p hex + * + * \param core Reference to RzCore instance + * \param addr Where the block of data to modify starts + * \param op Operation to perform on the block of data + * \param hex Optional hex string that may be required by the specific operation + * \param hexlen Optional length of the \p hex string. Must be present if \p hex is specified. + * \param buflen Used to return the length of the returned buffer + * \return The transformed buffer + */ +RZ_API RZ_OWN ut8 *rz_core_transform_op(RzCore *core, ut64 addr, RzCoreWriteOp op, ut8 *hex, int hexlen, int *buflen) { + rz_return_val_if_fail(core, NULL); + rz_return_val_if_fail(!hex || hexlen >= 0, NULL); + rz_return_val_if_fail(buflen, NULL); + + switch (op) { + case RZ_CORE_WRITE_OP_ADD: + case RZ_CORE_WRITE_OP_SUB: + case RZ_CORE_WRITE_OP_DIV: + case RZ_CORE_WRITE_OP_MUL: + case RZ_CORE_WRITE_OP_AND: + case RZ_CORE_WRITE_OP_OR: + case RZ_CORE_WRITE_OP_XOR: + case RZ_CORE_WRITE_OP_SHIFT_LEFT: + case RZ_CORE_WRITE_OP_SHIFT_RIGHT: + rz_return_val_if_fail(hex && hexlen >= 0, NULL); + break; + default: + break; + } + + ut8 *buf = RZ_NEWS(ut8, core->blocksize); + if (!buf) { + return NULL; + } + + int len = rz_io_nread_at(core->io, addr, buf, core->blocksize); + if (len < 0) { + free(buf); + return NULL; + } + + for (int i = 0, j = 0; i < len; i++, j = (j + 1) % (hexlen ? hexlen : 1)) { + ut16 tmp16; + ut32 tmp32; + ut64 tmp64; + switch (op) { + case RZ_CORE_WRITE_OP_BYTESWAP2: + if (i + 1 < len) { + tmp16 = rz_read_le16(buf + i); + rz_write_be16(buf + i, tmp16); + i++; + } + break; + case RZ_CORE_WRITE_OP_BYTESWAP4: + if (i + 3 < len) { + tmp32 = rz_read_le32(buf + i); + rz_write_be32(buf + i, tmp32); + i += 3; + } + break; + case RZ_CORE_WRITE_OP_BYTESWAP8: + if (i + 7 < len) { + tmp64 = rz_read_le64(buf + i); + rz_write_be64(buf + i, tmp64); + i += 7; + } + break; + case RZ_CORE_WRITE_OP_ADD: + buf[i] += hex[j]; + break; + case RZ_CORE_WRITE_OP_SUB: + buf[i] -= hex[j]; + break; + case RZ_CORE_WRITE_OP_DIV: + buf[i] = hex[j] ? buf[i] / hex[j] : 0; + break; + case RZ_CORE_WRITE_OP_MUL: + buf[i] *= hex[j]; + break; + case RZ_CORE_WRITE_OP_AND: + buf[i] &= hex[j]; + break; + case RZ_CORE_WRITE_OP_OR: + buf[i] |= hex[j]; + break; + case RZ_CORE_WRITE_OP_XOR: + buf[i] ^= hex[j]; + break; + case RZ_CORE_WRITE_OP_SHIFT_LEFT: + buf[i] <<= hex[j]; + break; + case RZ_CORE_WRITE_OP_SHIFT_RIGHT: + buf[i] >>= hex[j]; + break; + default: + rz_warn_if_reached(); + break; + } + } + *buflen = len; + return buf; +} + +/** + * \brief Write a full block of data according to the operation \p op and the hexvalue \p hex + * + * \param core Reference to RzCore instance + * \param addr Where the block of data to modify starts + * \param op Operation to perform on the block of data + * \param hex Optional hex string that may be required by the specific operation + * \param hexlen Optional length of the \p hex string. Must be present if \p hex is specified. + * \return true if the write operation succeeds, false otherwise + */ +RZ_API bool rz_core_write_block_op_at(RzCore *core, ut64 addr, RzCoreWriteOp op, ut8 *hex, int hexlen) { + int buflen; + ut8 *buf = rz_core_transform_op(core, addr, op, hex, hexlen, &buflen); + if (!buf) { + return false; + } + + if (!rz_core_write_at(core, addr, buf, buflen)) { + RZ_LOG_ERROR("Could not write block operation at %" PFMT64x "\n", addr); + free(buf); + return false; + } + + return true; +} + +/** + * \brief Write a full block of data with a sequence + * + * Write a full block of data with a sequence of numbers starting from \p from + * up to \p to, with a step of \p step. The values are written as numbers of + * \p value_size bytes. + * + * \param core Reference to RzCore instance + * \param addr Where the block of data to modify starts + * \param from From where to start the sequence of numbers + * \param to Where to stop in the sequence + * \param step Difference between two numbers in the sequence + * \param value_size Size of each number of the sequence, in bytes + * \return true if the write operation succeeds, false otherwise + */ +RZ_API bool rz_core_write_seq_at(RzCore *core, ut64 addr, ut64 from, ut64 to, ut64 step, int value_size) { + rz_return_val_if_fail(core, false); + rz_return_val_if_fail(value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8, false); + ut64 max_val = (1ULL << (8 * value_size)); + rz_return_val_if_fail(from < max_val, false); + rz_return_val_if_fail(to < max_val, false); + + ut8 *buf = RZ_NEWS0(ut8, core->blocksize); + if (!buf) { + return false; + } + + ut64 diff = to <= from ? max_val : to - from + 1; + ut64 p = from; + for (size_t i = 0; i < core->blocksize; i += value_size, p = (from + ((p + step - from) % diff)) % max_val) { + rz_write_ble(buf + i, p, rz_config_get_b(core->config, "cfg.bigendian"), value_size * 8); + } + + if (!rz_core_write_at(core, addr, buf, core->blocksize)) { + RZ_LOG_ERROR("Could not write sequence [%" PFMT64d ", %" PFMT64d "] step=%" PFMT64d ",value_size=%d at %" PFMT64x "\n", from, to, step, value_size, addr); + free(buf); + return false; + } + + free(buf); + return true; +} diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index 78b7ad9f0a..ed80543c68 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -4105,7 +4105,7 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(redirect_stmt) { // extract the string of the filename we need to write to TSNode arg = ts_node_child_by_field_name(node, "arg", strlen("arg")); - char *arg_str = ts_node_sub_string(arg, state->input); + char *arg_str = ts_node_handle_arg(state, node, arg, 2); if (arg_str[0] == '$') { // redirect output of command to an alias variable @@ -6038,7 +6038,6 @@ RZ_API void rz_core_cmd_init(RzCore *core) { { "q", "exit program session", rz_cmd_quit }, { "V", "enter visual mode", rz_cmd_visual }, { "v", "enter visual mode", rz_cmd_panels }, - { "w", "write bytes", rz_cmd_write }, { "x", "alias for px", rz_cmd_hexdump }, }; diff --git a/librz/core/cmd/cmd_print.c b/librz/core/cmd/cmd_print.c index 3ddb7311d5..95cffa22e0 100644 --- a/librz/core/cmd/cmd_print.c +++ b/librz/core/cmd/cmd_print.c @@ -2571,8 +2571,69 @@ static int cmd_print_pxA(RzCore *core, int len, const char *input) { return true; } +static ut8 *old_transform_op(RzCore *core, const char *val, char op, int *buflen) { + RzCoreWriteOp wop; + switch (op) { + case '2': + wop = RZ_CORE_WRITE_OP_BYTESWAP2; + break; + case '4': + wop = RZ_CORE_WRITE_OP_BYTESWAP4; + break; + case '8': + wop = RZ_CORE_WRITE_OP_BYTESWAP8; + break; + case 'a': + wop = RZ_CORE_WRITE_OP_ADD; + break; + case 'A': + wop = RZ_CORE_WRITE_OP_AND; + break; + case 'd': + wop = RZ_CORE_WRITE_OP_DIV; + break; + case 'l': + wop = RZ_CORE_WRITE_OP_SHIFT_LEFT; + break; + case 'm': + wop = RZ_CORE_WRITE_OP_MUL; + break; + case 'o': + wop = RZ_CORE_WRITE_OP_OR; + break; + case 'r': + wop = RZ_CORE_WRITE_OP_SHIFT_RIGHT; + break; + case 's': + wop = RZ_CORE_WRITE_OP_SUB; + break; + case 'x': + wop = RZ_CORE_WRITE_OP_XOR; + break; + default: + wop = RZ_CORE_WRITE_OP_XOR; + rz_warn_if_reached(); + break; + } + + ut8 *hex = NULL; + int hexlen = -1; + if (val) { + val = rz_str_trim_head_ro(val); + hex = RZ_NEWS(ut8, (strlen(val) + 1) / 2); + if (!hex) { + return NULL; + } + + hexlen = rz_hex_str2bin(val, hex); + } + return rz_core_transform_op(core, core->offset, wop, hex, hexlen, buflen); +} + static void cmd_print_op(RzCore *core, const char *input) { ut8 *buf; + int buflen = -1; + if (!input[0]) return; switch (input[1]) { @@ -2588,13 +2649,13 @@ static void cmd_print_op(RzCore *core, const char *input) { case '2': case '4': if (input[2]) { // parse val from arg - buf = rz_core_transform_op(core, input + 3, input[1]); + buf = old_transform_op(core, input + 3, input[1], &buflen); } else { // use clipboard instead of val - buf = rz_core_transform_op(core, NULL, input[1]); + buf = old_transform_op(core, NULL, input[1], &buflen); } break; case 'n': - buf = rz_core_transform_op(core, "ff", 'x'); + buf = old_transform_op(core, "ff", 'x', &buflen); break; case '\0': case '?': @@ -2604,7 +2665,7 @@ static void cmd_print_op(RzCore *core, const char *input) { } if (buf) { rz_print_hexdump(core->print, core->offset, buf, - core->blocksize, 16, 1, 1); + buflen, 16, 1, 1); free(buf); } } diff --git a/librz/core/cmd/cmd_write.c b/librz/core/cmd/cmd_write.c index ae5dcd7a0a..d0d9e082fb 100644 --- a/librz/core/cmd/cmd_write.c +++ b/librz/core/cmd/cmd_write.c @@ -7,90 +7,6 @@ #include "rz_core.h" #include "rz_io.h" -static const char *help_msg_w[] = { - "Usage:", "w[x] [str] [>= shift right", - "woR", "", "random bytes (alias for 'wr $b')", - "wos", " [val]", "-= substraction", - "wow", " [val]", "== write looped value (alias for 'wb')", - "wox", " [val]", "^= xor (f.ex: wox 0x90)", - NULL -}; - -static const char *help_msg_wop[] = { - "Usage:", "wop[DO]", " len @ addr | value", - "wopD", " len [@ addr]", "Write a De Bruijn Pattern of length 'len' at address 'addr'", - "wopD*", " len [@ addr]", "Show wx command that creates a debruijn pattern of a specific length", - "wopO", " value", "Finds the given value into a De Bruijn Pattern at current offset", - NULL -}; - -static const char *help_msg_wt[] = { - "Usage:", "wt[a] file [size]", " Write 'size' bytes in current block to 'file'", - "wta", " [filename]", "append to 'filename'", - "wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')", - "wtf!", " [filename]", "write to file from current address to eof", - "wtff", " [prefix]", "write block from current seek to [prefix]-[offset]", - "wts", " host:port [sz]", "send data to remote host:port via tcp://", - NULL -}; - -static const char *help_msg_wf[] = { - "Usage:", "wf[fs] [-|args ..]", " Write from (file, swap, offset)", - "wf", " 10 20", "write 20 bytes from offset 10 into current seek", - "wff", " file [len]", "write contents of file into current offset", - "wfs", " host:port [len]", "write from socket (tcp listen in port for N bytes)", - "wfx", " 10 20", "exchange 20 bytes betweet current offset and 10", - NULL -}; - static void cmd_write_fail(RzCore *core) { eprintf("Failed to write\n"); core->num->value = 1; @@ -171,157 +87,6 @@ static void cmd_write_bits(RzCore *core, int set, ut64 val) { } } -static void wo_show_algorithms(char c) { - char flags[5] = { 0 }; - - eprintf("Usage: wo%c [algo] [key] [IV]\n", c); - eprintf(" flags algorithm license author\n"); - - const RzCryptoPlugin *rcp; - for (size_t i = 0; (rcp = rz_crypto_plugin_by_index(i)); i++) { - if (!strncmp("base", rcp->name, 4) || !strcmp("punycode", rcp->name)) { - snprintf(flags, sizeof(flags), "__ed"); - } else if (!strcmp("rol", rcp->name)) { - snprintf(flags, sizeof(flags), "E___"); - } else if (!strcmp("ror", rcp->name)) { - snprintf(flags, sizeof(flags), "_D__"); - } else { - snprintf(flags, sizeof(flags), "ED__"); - } - eprintf(" %-5s %-14s %-10s %s\n", flags, rcp->name, rcp->license, rcp->author); - } - eprintf( - "\n" - "flags legenda:\n" - " E = encryption, D = decryption\n" - " e = encoding, d = encoding\n"); -} - -RZ_IPI int rz_wo_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - ut8 *buf; - int len; - int value; - switch (input[0]) { - case 'e': - if (input[1] != ' ') { - rz_cons_printf("Usage: 'woe from-to step'\n"); - return -1; - } - /* fallthru */ - case 'a': - case 's': - case 'A': - case 'x': - case 'r': - case 'l': - case 'm': - case 'd': - case 'o': - case 'w': - case '2': // "wo2" - case '4': // "wo4" - case '8': // "wo8" - if (input[1]) { // parse val from arg - rz_core_write_op(core, input + 2, input[0]); - } else { // use clipboard instead of val - rz_core_write_op(core, NULL, input[0]); - } - rz_core_block_read(core); - break; - case 'R': - rz_core_cmd0(core, "wr $b"); - break; - case 'n': - rz_core_write_op(core, "ff", 'x'); - rz_core_block_read(core); - break; - case 'E': // "woE" encrypt - case 'D': // "woD" decrypt - { - int direction = (input[0] == 'E') ? 0 : 1; - const char *algo = NULL; - const char *key = NULL; - const char *iv = NULL; - char *space, *args = strdup(rz_str_trim_head_ro(input + 1)); - space = strchr(args, ' '); - if (space) { - *space++ = 0; - key = space; - space = strchr(key, ' '); - if (space) { - *space++ = 0; - iv = space; - } - } - algo = args; - if (algo && *algo && key) { - encrypt_or_decrypt_block(core, algo, key, direction, iv); - } else { - if (input[1] == '?') { - wo_show_algorithms(input[0]); - } else { - eprintf("Usage: wo%c [algo] [key] [IV] (use wo%c? for the algorithms list)\n", input[0], input[0]); - } - } - free(args); - } break; - case 'p': // debrujin patterns - switch (input[1]) { - case 'D': // "wopD" - { - char *sp = strchr(input, ' '); - len = sp ? rz_num_math(core->num, sp + 1) : core->blocksize; - } - if (len > 0) { - /* XXX This seems to fail at generating long patterns (wopD 512K) */ - buf = (ut8 *)rz_debruijn_pattern(len, 0, NULL); // debruijn_charset); - if (buf) { - const ut8 *ptr = buf; - ut64 addr = core->offset; - if (input[2] == '*') { - int i; - rz_cons_printf("wx "); - for (i = 0; i < len; i++) { - rz_cons_printf("%02x", buf[i]); - } - rz_cons_newline(); - } else { - if (!rz_core_write_at(core, addr, ptr, len)) { - cmd_write_fail(core); - } - } - free(buf); - } else { - eprintf("Couldn't generate pattern of length %d\n", len); - } - } - break; - case 'O': // "wopO" - if (strlen(input) > 3 && strncmp(input + 3, "0x", 2)) { - eprintf("Need hex value with `0x' prefix e.g. 0x41414142\n"); - } else if (input[2] == ' ') { - value = rz_num_get(core->num, input + 3); - core->num->value = rz_debruijn_offset(value, rz_config_get_i(core->config, "cfg.bigendian")); - rz_cons_printf("%" PFMT64d "\n", core->num->value); - } - break; - case '\0': - case '?': - default: - rz_core_cmd_help(core, help_msg_wop); - break; - } - break; - case '\0': - case '?': - default: - rz_core_cmd_help(core, help_msg_wo); - break; - } - return 0; -} - #define WSEEK(x, y) \ if (wseek) \ rz_core_seek_delta(x, y, true) @@ -364,59 +129,6 @@ RZ_IPI RzCmdStatus rz_write_base64_decode_handler(RzCore *core, int argc, const return rz_core_write_base64d_at(core, core->offset, argv[1]) ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR; } -static bool cmd_wff(RzCore *core, const char *input) { - ut8 *buf; - size_t size; - // XXX: file names cannot contain spaces - const char *arg = input + ((input[0] == ' ') ? 1 : 0); - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - char *p, *a = rz_str_trim_dup(arg); - p = strchr(a, ' '); - if (p) { - *p++ = 0; - } - - if (*arg == '?' || !*arg) { - eprintf("Usage: wf [file] ([size] ([offset]))\n"); - } - if (!strcmp(arg, "-")) { - char *out = rz_core_editor(core, NULL, NULL); - if (out) { - if (!rz_io_write_at(core->io, core->offset, - (ut8 *)out, strlen(out))) { - eprintf("rz_io_write_at failed at 0x%08" PFMT64x "\n", core->offset); - } - rz_core_block_read(core); - free(out); - } - } - if ((buf = (ut8 *)rz_file_slurp(a, &size))) { - int u_offset = 0; - ut64 u_size = rz_num_math(core->num, p); - if (u_size < 1) - u_size = (ut64)size; - if (p) { - *p++ = 0; - u_offset = rz_num_math(core->num, p); - if (u_offset > size) { - eprintf("Invalid offset\n"); - free(buf); - return false; - } - } - rz_io_use_fd(core->io, core->file->fd); - if (!rz_io_write_at(core->io, core->offset, buf + u_offset, (int)u_size)) { - eprintf("rz_io_write_at failed at 0x%08" PFMT64x "\n", core->offset); - } - WSEEK(core, size); - free(buf); - rz_core_block_read(core); - } else { - eprintf("Cannot open file '%s'\n", arg); - } - return true; -} - static bool ioMemcpy(RzCore *core, ut64 dst, ut64 src, int len) { bool ret = false; if (len > 0) { @@ -438,99 +150,6 @@ static bool ioMemcpy(RzCore *core, ut64 dst, ut64 src, int len) { return ret; } -static bool cmd_wfx(RzCore *core, const char *input) { - char *args = rz_str_trim_dup(input); - char *arg = strchr(args, ' '); - int len = core->blocksize; - if (arg) { - *arg = 0; - len = rz_num_math(core->num, arg + 1); - } - ut64 dst = core->offset; - ut64 src = rz_num_math(core->num, args); - if (len > 0) { - // cache dest, memcpy, write cache - ut8 *buf = calloc(1, len); - if (buf) { - if (rz_io_read_at(core->io, dst, buf, len)) { - ioMemcpy(core, core->offset, src, len); - if (rz_io_write_at(core->io, src, buf, len)) { - rz_core_block_read(core); - } else { - eprintf("Failed to write at 0x%08" PFMT64x "\n", src); - } - } else { - eprintf("cmd_wfx: failed to read at 0x%08" PFMT64x "\n", dst); - } - free(buf); - } - } - free(args); - return true; -} - -static bool cmd_wfs(RzCore *core, const char *input) { - char *str = strdup(input); - if (str[0] != ' ') { - eprintf("Usage wfs host:port [sz]\n"); - free(str); - return false; - } - ut64 addr = 0; - char *host = str + 1; - char *port = strchr(host, ':'); - if (!port) { - eprintf("Usage wfs host:port [sz]\n"); - free(str); - return false; - } - ut64 sz = core->blocksize; - *port++ = 0; - char *space = strchr(port, ' '); - if (space) { - *space++ = 0; - sz = rz_num_math(core->num, space); - addr = core->offset; - } - ut8 *buf = calloc(1, sz); - if (!buf) { - free(str); - return false; - } - rz_io_read_at(core->io, addr, buf, sz); - RzSocket *s = rz_socket_new(false); - if (!rz_socket_listen(s, port, NULL)) { - eprintf("Cannot listen on port %s\n", port); - rz_socket_free(s); - free(str); - free(buf); - return false; - } - int done = 0; - RzSocket *c = rz_socket_accept(s); - if (c) { - eprintf("Receiving data from client...\n"); - while (done < sz) { - int rc = rz_socket_read(c, buf + done, sz - done); - if (rc < 1) { - eprintf("oops\n"); - break; - } - done += rc; - } - rz_socket_free(c); - if (rz_io_write_at(core->io, core->offset, buf, done)) { - eprintf("Written %d bytes\n", done); - } else { - eprintf("Cannot write\n"); - } - } - rz_socket_free(s); - free(buf); - free(str); - return true; -} - RZ_IPI RzCmdStatus rz_write_from_io_handler(RzCore *core, int argc, const char **argv) { ut64 addr = rz_num_math(core->num, argv[1]); ut64 len = rz_num_math(core->num, argv[2]); @@ -673,55 +292,6 @@ err: return res; } -RZ_IPI int rz_wf_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - if (!core || !*input) { - return -1; - } - if (input[0] == '?') { - eprintf("Usage: wf [file] ([size] ([offset]))\n"); - rz_core_cmd_help(core, help_msg_wf); - return -1; - } - if (input[0] == 's') { // "wfs" - return cmd_wfs(core, input + 1); - } - if (input[0] == 'x') { // "wfx" - return cmd_wfx(core, input + 1); - } - if (input[0] == 'f') { // "wff" - return cmd_wff(core, input + 1); - } - char *args = rz_str_trim_dup(input); - char *arg = strchr(args, ' '); - int len = core->blocksize; - if (arg) { - *arg++ = 0; - len = rz_num_math(core->num, arg); - } - ut64 addr = rz_num_math(core->num, args); - ioMemcpy(core, core->offset, addr, len); - free(args); - rz_core_block_read(core); - return 0; -} - -RZ_IPI int rz_wB_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - switch (input[0]) { - case ' ': - cmd_write_bits(core, 1, rz_num_math(core->num, input + 1)); - break; - case '-': - cmd_write_bits(core, 0, rz_num_math(core->num, input + 1)); - break; - default: - eprintf("Usage: wB 0x2000 # or wB-0x2000\n"); - break; - } - return 0; -} - RZ_IPI RzCmdStatus rz_write_bits_handler(RzCore *core, int argc, const char **argv) { cmd_write_bits(core, 1, rz_num_math(core->num, argv[1])); return RZ_CMD_STATUS_OK; @@ -732,31 +302,6 @@ RZ_IPI RzCmdStatus rz_write_unset_bits_handler(RzCore *core, int argc, const cha return RZ_CMD_STATUS_OK; } -static int w0_handler_common(RzCore *core, ut64 len) { - int res = 0; - if (len > 0) { - ut8 *buf = calloc(1, len); - if (buf) { - if (!rz_io_write_at(core->io, core->offset, buf, len)) { - eprintf("rz_io_write_at failed at 0x%08" PFMT64x "\n", core->offset); - res = -1; - } - rz_core_block_read(core); - free(buf); - } else { - eprintf("Cannot allocate %d byte(s)\n", (int)len); - res = -1; - } - } - return res; -} - -RZ_IPI int rz_w0_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - ut64 len = rz_num_math(core->num, input); - return w0_handler_common(core, len); -} - RZ_IPI RzCmdStatus rz_write_zero_handler(RzCore *core, int argc, const char **argv) { ut64 len = rz_num_math(core->num, argv[1]); ut8 *buf = RZ_NEWS0(ut8, len); @@ -808,131 +353,67 @@ RZ_IPI RzCmdStatus rz_write_8_dec_handler(RzCore *core, int argc, const char **a return w_incdec_handler(core, argc, argv, 8); } -RZ_IPI int rz_w6_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - int fail = 0; - ut8 *buf = NULL; - int len = 0, str_len; - const char *str; - - if (input[0] && input[1] != ' ') - fail = 1; - - if (input[0] && input[1] && input[2]) - str = input + 2; - else - str = ""; - str_len = strlen(str) + 1; - if (!fail) { - switch (input[0]) { - case 'd': // "w6d" - buf = malloc(str_len); - if (!buf) { - eprintf("Error: failed to malloc memory"); - break; - } - len = rz_base64_decode(buf, str, -1); - if (len < 0) { - free(buf); - fail = 1; - } - break; - case 'e': { // "w6e" - ut8 *bin_buf = malloc(str_len); - if (!bin_buf) { - eprintf("Error: failed to malloc memory"); - break; - } - const int bin_len = rz_hex_str2bin(str, bin_buf); - if (bin_len <= 0) { - fail = 1; - } else { - buf = calloc(str_len + 1, 4); - len = rz_base64_encode((char *)buf, bin_buf, bin_len); - if (len == 0) { - free(buf); - fail = 1; - } - } - free(bin_buf); - break; - } - default: - fail = 1; - break; - } - } - if (!fail) { - if (!rz_core_write_at(core, core->offset, buf, len)) { - cmd_write_fail(core); - } - WSEEK(core, len); - rz_core_block_read(core); - free(buf); - } else { - eprintf("Usage: w6[de] base64/hex\n"); - } - return 0; -} - -RZ_IPI int rz_wu_handler_old(void *data, const char *input) { +RZ_IPI RzCmdStatus rz_write_unified_patch_handler(RzCore *core, int argc, const char **argv) { // TODO: implement it in an API RzCore.write_unified_hexpatch() is ETOOLONG - if (input[0] == ' ') { - char *data = rz_file_slurp(input + 1, NULL); - if (data) { - int i; - char sign = ' '; - int line = 0, offs = 0, hexa = 0; - int newline = 1; - for (i = 0; data[i]; i++) { - switch (data[i]) { - case '+': - if (newline) - sign = 1; - break; - case '-': - if (newline) { - sign = 0; - offs = i + ((data[i + 1] == ' ') ? 2 : 1); - } - break; - case ' ': - data[i] = 0; - if (sign) { - if (!line) - line = i + 1; - else if (!hexa) - hexa = i + 1; - } - break; - case '\r': - break; - case '\n': - newline = 1; - if (sign == ' ') { - offs = 0; - line = 0; - hexa = 0; - } else if (sign) { - if (offs && hexa) { - rz_cons_printf("wx %s @ %s\n", data + hexa, data + offs); - } else - eprintf("food\n"); - offs = 0; - line = 0; - } else - hexa = 0; - sign = -1; - continue; - } - newline = 0; - } - free(data); - } - } else { - eprintf("|Usage: wu [unified-diff-patch] # see 'cu'\n"); + char *data = rz_file_slurp(argv[1], NULL); + if (!data) { + RZ_LOG_ERROR("Cannot read data from %s.\n", argv[1]); + return RZ_CMD_STATUS_ERROR; } + int i; + char sign = ' '; + int line = 0, offs = 0, hexa = 0; + int newline = 1; + for (i = 0; data[i]; i++) { + switch (data[i]) { + case '+': + if (newline) + sign = 1; + break; + case '-': + if (newline) { + sign = 0; + offs = i + ((data[i + 1] == ' ') ? 2 : 1); + } + break; + case ' ': + data[i] = 0; + if (sign) { + if (!line) + line = i + 1; + else if (!hexa) + hexa = i + 1; + } + break; + case '\r': + break; + case '\n': + newline = 1; + if (sign == ' ') { + offs = 0; + line = 0; + hexa = 0; + } else if (sign) { + if (offs && hexa) { + ut64 dst = rz_num_math(core->num, data + offs); + ut8 *buf = RZ_NEWS(ut8, strlen(data + hexa)); + if (buf) { + int len = rz_hex_str2bin(data + hexa, buf); + rz_core_write_at(core, dst, buf, len); + } + } else { + eprintf("food\n"); + } + offs = 0; + line = 0; + } else + hexa = 0; + sign = -1; + continue; + } + newline = 0; + } + free(data); return 0; } @@ -945,252 +426,16 @@ RZ_IPI RzCmdStatus rz_write_random_handler(RzCore *core, int argc, const char ** return rz_core_write_random_at(core, core->offset, length) ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR; } -static void w_handler_common(RzCore *core, const char *input) { - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - char *str = strdup(input); - /* write string */ - int len = rz_str_unescape(str); - if (!rz_core_write_at(core, core->offset, (const ut8 *)str, len)) { - cmd_write_fail(core); - } - free(str); - WSEEK(core, len); - rz_core_block_read(core); -} - -RZ_IPI int rz_w_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - w_handler_common(core, input); - return 0; -} - RZ_IPI RzCmdStatus rz_write_handler(RzCore *core, int argc, const char **argv) { - return rz_core_write_string_at(core, core->offset, argv[1]) ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR; + return bool2status(rz_core_write_string_at(core, core->offset, argv[1])); } -RZ_IPI int rz_wz_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - char *str = strdup(input); - /* write zero-terminated string */ - int len = rz_str_unescape(str); - if (!rz_core_write_at(core, core->offset, (const ut8 *)str + 1, len)) { - cmd_write_fail(core); - } - if (len > 0) { - core->num->value = len; - } else { - core->num->value = 0; - } -#if 0 - rz_io_use_desc (core->io, core->file->desc); -#endif - WSEEK(core, len + 1); - rz_core_block_read(core); - return 0; +RZ_IPI RzCmdStatus rz_write_zero_string_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_core_write_string_zero_at(core, core->offset, argv[1])); } -RZ_IPI int rz_wt_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - char *str = strdup(input); - char *ostr = str; - const char *filename = ""; - char _fn[32]; - _fn[0] = 0; - char *tmp; - if (*str == 's') { // "wts" - if (str[1] == ' ') { - eprintf("Write to server\n"); - st64 sz = rz_io_size(core->io); - if (sz > 0) { - ut64 addr = 0; - char *host = str + 2; - char *port = strchr(host, ':'); - if (port) { - *port++ = 0; - char *space = strchr(port, ' '); - if (space) { - *space++ = 0; - sz = rz_num_math(core->num, space); - addr = core->offset; - } - ut8 *buf = calloc(1, sz); - rz_io_read_at(core->io, addr, buf, sz); - RzSocket *s = rz_socket_new(false); - if (rz_socket_connect(s, host, port, RZ_SOCKET_PROTO_TCP, 0)) { - int done = 0; - eprintf("Transfering file to the end-point...\n"); - while (done < sz) { - int rc = rz_socket_write(s, buf + done, sz - done); - if (rc < 1) { - eprintf("oops\n"); - break; - } - done += rc; - } - } else { - eprintf("Cannot connect\n"); - } - rz_socket_free(s); - free(buf); - } else { - eprintf("Usage wts host:port [sz]\n"); - } - } else { - eprintf("Unknown file size\n"); - } - } else { - eprintf("Usage wts host:port [sz]\n"); - } - } else if (*str == '?' || *str == '\0') { - rz_core_cmd_help(core, help_msg_wt); - free(ostr); - return 0; - } else { - bool append = false; - bool toend = false; - st64 sz = core->blocksize; - ut64 poff = core->offset; - if (*str == 'f') { // "wtf" - str++; - if (*str == '?') { - rz_core_cmd_help(core, help_msg_wt); - return 0; - } - if (*str == '!') { - if (str[1] == '?') { - rz_core_cmd_help(core, help_msg_wt); - return 0; - } - RzIOMap *map = rz_io_map_get(core->io, poff); - toend = true; - // use physical address - poff = map ? poff - map->itv.addr + map->delta : poff; - str++; - } - if (*str == 'f') { // "wtff" - if (str[1] == '?') { - rz_core_cmd_help(core, help_msg_wt); - return 0; - } - const char *prefix = rz_str_trim_head_ro(str + 2); - if (!*prefix) { - prefix = "dump"; - } - str++; - filename = rz_str_newf("%s-0x%08" PFMT64x, prefix, core->offset); - } else { - if (*str) { - if (str[1] == '?') { - rz_core_cmd_help(core, help_msg_wt); - return 0; - } - filename = rz_str_trim_head_ro(str); - } else { - filename = ""; - } - } - } else if (*str == 'a') { // "wta" - append = 1; - str++; - if (str[0] == ' ') { - filename = str + 1; - } else { - const char *prefix = rz_config_get(core->config, "cfg.prefixdump"); - snprintf(_fn, sizeof(_fn), "%s.0x%08" PFMT64x, prefix, poff); - filename = _fn; - } - } else if (*str != ' ') { - const char *prefix = rz_config_get(core->config, "cfg.prefixdump"); - snprintf(_fn, sizeof(_fn), "%s.0x%08" PFMT64x, prefix, poff); - filename = _fn; - } else { - filename = str + 1; - } - tmp = *str ? strchr(str + 1, ' ') : NULL; - if (!filename || !*filename) { - const char *prefix = rz_config_get(core->config, "cfg.prefixdump"); - snprintf(_fn, sizeof(_fn), "%s.0x%08" PFMT64x, prefix, poff); - filename = _fn; - } - if (tmp) { - if (toend) { - sz = rz_io_fd_size(core->io, core->file->fd) - core->offset; - if (sz < 0) { - eprintf("Warning: File size is unknown."); - } - } else { - sz = (st64)rz_num_math(core->num, tmp + 1); - *tmp = 0; - } - if ((st64)sz < 1) { - sz = 0; - } else if (!rz_core_dump(core, filename, poff, (ut64)sz, append)) { - sz = -1; - } - } else { - if (toend) { - sz = rz_io_fd_size(core->io, core->file->fd); - if (sz < 0) { - eprintf("Warning: File size is unknown."); - } - if (sz != -1 && core->offset <= sz) { - sz -= core->offset; - if (!rz_core_dump(core, filename, core->offset, (ut64)sz, append)) { - sz = -1; - } - } else { - sz = -1; - } - } else { - sz = core->blocksize; - if (!rz_file_dump(filename, core->block, sz, append)) { - sz = -1; - } - } - } - if (sz >= 0) { - eprintf("Dumped %" PFMT64d " bytes from 0x%08" PFMT64x " into %s\n", - sz, poff, filename); - } - } - return 0; -} - -RZ_IPI int rz_ww_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - char *str = strdup(input); - int len = rz_str_unescape(str); - if (len < 1) { - return 0; - } - len++; - str++; - len = (len - 1) << 1; - char *tmp = (len > 0) ? malloc(len + 1) : NULL; - if (tmp) { - int i; - for (i = 0; i < len; i++) { - if (i % 2) - tmp[i] = 0; - else - tmp[i] = str[i >> 1]; - } - str = tmp; - if (core->file) { - rz_io_use_fd(core->io, core->file->fd); - } - if (!rz_io_write_at(core->io, core->offset, (const ut8 *)str, len)) { - eprintf("rz_io_write_at failed at 0x%08" PFMT64x "\n", core->offset); - } - WSEEK(core, len); - rz_core_block_read(core); - free(tmp); - } else { - eprintf("Cannot malloc %d\n", len); - } - return 0; +RZ_IPI RzCmdStatus rz_write_wide_string_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_core_write_string_wide_at(core, core->offset, argv[1])); } RZ_IPI RzCmdStatus rz_write_hex_handler(RzCore *core, int argc, const char **argv) { @@ -1277,106 +522,44 @@ RZ_IPI RzCmdStatus rz_write_block_handler(RzCore *core, int argc, const char **a return bool2status(rz_core_write_block(core, core->offset, hex, len)); } -RZ_IPI int rz_wm_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - char *str = strdup(input); - int size = rz_hex_str2bin(input, (ut8 *)str); - int wseek = rz_config_get_i(core->config, "cfg.wseek"); - switch (input[0]) { - case '\0': - eprintf("TODO: Display current write mask"); - break; - case '?': - break; - case '-': - rz_io_set_write_mask(core->io, 0, 0); - eprintf("Write mask disabled\n"); - break; - case ' ': - if (size > 0) { - rz_io_use_fd(core->io, core->file->fd); - rz_io_set_write_mask(core->io, (const ut8 *)str, size); - WSEEK(core, size); - eprintf("Write mask set to '"); - size_t i; - for (i = 0; i < size; i++) { - eprintf("%02x", str[i]); - } - eprintf("'\n"); - } else { - eprintf("Invalid string\n"); - } - break; +RZ_IPI RzCmdStatus rz_write_mask_set_handler(RzCore *core, int argc, const char **argv) { + ut8 *buf = RZ_NEWS(ut8, strlen(argv[1]) / 2); + if (!buf) { + return RZ_CMD_STATUS_ERROR; } - return 0; + int size = rz_hex_str2bin(argv[1], buf); + return bool2status(rz_io_set_write_mask(core->io, buf, size)); } -RZ_IPI int rz_wd_handler_old(void *data, const char *input) { - RzCore *core = (RzCore *)data; - if (input[0] && input[0] == ' ') { - char *arg, *inp = strdup(input + 1); - arg = strchr(inp, ' '); - if (arg) { - *arg = 0; - ut64 addr = rz_num_math(core->num, input + 1); - ut64 len = rz_num_math(core->num, arg + 1); - ut8 *data = malloc(len); - rz_io_read_at(core->io, addr, data, len); - if (!rz_io_write_at(core->io, core->offset, data, len)) { - eprintf("rz_io_write_at failed at 0x%08" PFMT64x "\n", core->offset); - } - free(data); - } else { - eprintf("See wd?\n"); - } - free(inp); - } else - eprintf("Usage: wd [source-offset] [length] @ [dest-offset]\n"); - return 0; +RZ_IPI RzCmdStatus rz_write_mask_reset_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_io_set_write_mask(core->io, NULL, 0)); +} + +RZ_IPI RzCmdStatus rz_write_duplicate_handler(RzCore *core, int argc, const char **argv) { + ut64 src = rz_num_math(core->num, argv[1]); + ut64 len = rz_num_math(core->num, argv[2]); + ut8 *data = RZ_NEWS(ut8, len); + if (!data) { + return RZ_CMD_STATUS_ERROR; + } + + int n = rz_io_nread_at(core->io, src, data, len); + if (n < 0) { + free(data); + RZ_LOG_ERROR("Cannot read data from %" PFMT64x ".\n", src); + return RZ_CMD_STATUS_ERROR; + } + if (!rz_core_write_at(core, core->offset, data, n)) { + RZ_LOG_ERROR("Cannot write %d bytes to %" PFMT64x ".\n", n, core->offset); + return RZ_CMD_STATUS_ERROR; + } + return RZ_CMD_STATUS_OK; } RZ_IPI RzCmdStatus rz_write_length_string_handler(RzCore *core, int argc, const char **argv) { return rz_core_write_length_string_at(core, core->offset, argv[1]) ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR; } -/* TODO: simplify using rz_write */ -RZ_IPI int rz_cmd_write(void *data, const char *input) { - RzCore *core = (RzCore *)data; - - if (!input) { - return 0; - } - - switch (*input) { - case 'u': // "wu" - rz_wu_handler_old(core, input + 1); - break; - case 'z': // "wz" - rz_wz_handler_old(core, input + 1); - break; - case 't': // "wt" - rz_wt_handler_old(core, input + 1); - break; - case 'w': // "ww" - rz_ww_handler_old(core, input + 1); - break; - case 'm': // "wm" - rz_wm_handler_old(core, input + 1); - break; - case 'o': // "wo" - rz_wo_handler_old(core, input + 1); - break; - case 'd': // "wd" - rz_wd_handler_old(core, input + 1); - break; - default: - case '?': // "w?" - rz_core_cmd_help(core, help_msg_w); - break; - } - return 0; -} - RZ_IPI RzCmdStatus rz_write_cache_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { return rz_core_io_cache_print(core, state); } @@ -1482,3 +665,132 @@ RZ_IPI RzCmdStatus rz_write_extend_hexbytes_handler(RzCore *core, int argc, cons } return bool2status(rz_core_write_at(core, addr, bytes, len)); } + +RZ_IPI RzCmdStatus rz_write_op_2byteswap_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_core_write_block_op_at(core, core->offset, RZ_CORE_WRITE_OP_BYTESWAP2, NULL, 0)); +} + +RZ_IPI RzCmdStatus rz_write_op_4byteswap_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_core_write_block_op_at(core, core->offset, RZ_CORE_WRITE_OP_BYTESWAP4, NULL, 0)); +} + +RZ_IPI RzCmdStatus rz_write_op_8byteswap_handler(RzCore *core, int argc, const char **argv) { + return bool2status(rz_core_write_block_op_at(core, core->offset, RZ_CORE_WRITE_OP_BYTESWAP8, NULL, 0)); +} + +static RzCmdStatus write_op_val(RzCore *core, int argc, const char **argv, RzCoreWriteOp op) { + rz_return_val_if_fail(argc > 1, RZ_CMD_STATUS_WRONG_ARGS); + + ut8 *hex = RZ_NEWS(ut8, (strlen(argv[1]) + 1) / 2); + if (!hex) { + return RZ_CMD_STATUS_ERROR; + } + + int hexlen = rz_hex_str2bin(argv[1], hex); + RzCmdStatus res = bool2status(rz_core_write_block_op_at(core, core->offset, op, hex, hexlen)); + free(hex); + return res; +} + +RZ_IPI RzCmdStatus rz_write_op_add_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_ADD); +} + +RZ_IPI RzCmdStatus rz_write_op_sub_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_SUB); +} + +RZ_IPI RzCmdStatus rz_write_op_mul_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_MUL); +} + +RZ_IPI RzCmdStatus rz_write_op_div_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_DIV); +} + +RZ_IPI RzCmdStatus rz_write_op_xor_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_XOR); +} + +RZ_IPI RzCmdStatus rz_write_op_and_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_AND); +} + +RZ_IPI RzCmdStatus rz_write_op_or_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_OR); +} + +RZ_IPI RzCmdStatus rz_write_op_shl_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_SHIFT_LEFT); +} + +RZ_IPI RzCmdStatus rz_write_op_shr_handler(RzCore *core, int argc, const char **argv) { + return write_op_val(core, argc, argv, RZ_CORE_WRITE_OP_SHIFT_RIGHT); +} + +RZ_IPI RzCmdStatus rz_write_op_encrypt_handler(RzCore *core, int argc, const char **argv) { + const char *algo = argv[1]; + const char *key = argv[2]; + const char *iv = argv[3]; + return bool2status(encrypt_or_decrypt_block(core, algo, key, 0, iv)); +} + +RZ_IPI RzCmdStatus rz_write_op_decrypt_handler(RzCore *core, int argc, const char **argv) { + const char *algo = argv[1]; + const char *key = argv[2]; + const char *iv = argv[3]; + return bool2status(encrypt_or_decrypt_block(core, algo, key, 1, iv)); +} + +RZ_IPI RzCmdStatus rz_write_op_sequence_handler(RzCore *core, int argc, const char **argv) { + ut64 from = rz_num_math(NULL, argv[1]); + ut64 to = rz_num_math(NULL, argv[2]); + ut64 step = rz_num_math(NULL, argv[3]); + int value_size = (int)rz_num_math(NULL, argv[4]); + if (step < 1) { + RZ_LOG_ERROR("Invalid value: %" PFMT64d "\n", step); + return RZ_CMD_STATUS_ERROR; + } + if (value_size != 1 && value_size != 2 && value_size != 4 && value_size != 8) { + RZ_LOG_ERROR("Invalid value: %d\n", value_size); + return RZ_CMD_STATUS_ERROR; + } + ut64 max_val = (1ULL << (8 * value_size)); + if (from >= max_val) { + RZ_LOG_ERROR("Invalid value: %" PFMT64d "\n", from); + return RZ_CMD_STATUS_ERROR; + } + if (to >= max_val) { + RZ_LOG_ERROR("Invalid value: %" PFMT64d "\n", to); + return RZ_CMD_STATUS_ERROR; + } + + return bool2status(rz_core_write_seq_at(core, core->offset, from, to, step, value_size)); +} + +RZ_IPI RzCmdStatus rz_write_debruijn_handler(RzCore *core, int argc, const char **argv) { + int len = (int)rz_num_math(core->num, argv[1]); + if (len < 0) { + RZ_LOG_ERROR("Invalid length: %d\n", len); + return RZ_CMD_STATUS_ERROR; + } + char *p = rz_debruijn_pattern(len, 0, NULL); + if (!p) { + RZ_LOG_ERROR("Cannot create Debrujn sequence of length %d\n", len); + return RZ_CMD_STATUS_ERROR; + } + bool res = rz_core_write_string_at(core, core->offset, p); + free(p); + return bool2status(res); +} + +RZ_IPI RzCmdStatus rz_write_debruijn_find_handler(RzCore *core, int argc, const char **argv) { + ut64 value = rz_num_math(core->num, argv[1]); + int offset = rz_debruijn_offset(0, NULL, value, rz_config_get_b(core->config, "cfg.bigendian")); + if (offset < 0) { + RZ_LOG_ERROR("Could not find value %" PFMT64x " in Debruijn sequence.\n", value); + return RZ_CMD_STATUS_ERROR; + } + rz_cons_printf("%d\n", offset); + return RZ_CMD_STATUS_OK; +} diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index d9542129a3..372914ebae 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -46,6 +46,8 @@ static const RzCmdDescDetail w8_details[2]; static const RzCmdDescDetail w6_details[2]; static const RzCmdDescDetail write_extend_hexbytes_details[2]; static const RzCmdDescDetail write_assembly_opcode_details[2]; +static const RzCmdDescDetail write_op_sequence_details[2]; +static const RzCmdDescDetail wo_details[2]; static const RzCmdDescDetail zign_add_details[5]; static const RzCmdDescDetail tmp_modifiers_details[2]; static const RzCmdDescDetail iterators_details[2]; @@ -471,15 +473,18 @@ static const RzCmdDescArg write_base64_encode_args[2]; static const RzCmdDescArg write_extend_zero_args[3]; static const RzCmdDescArg write_extend_shift_args[3]; static const RzCmdDescArg write_extend_hexbytes_args[3]; +static const RzCmdDescArg write_unified_patch_args[2]; static const RzCmdDescArg write_random_args[2]; static const RzCmdDescArg write_cache_remove_args[3]; static const RzCmdDescArg write_cache_commit_args[3]; static const RzCmdDescArg write_pcache_list_args[2]; static const RzCmdDescArg write_pcache_commit_args[2]; +static const RzCmdDescArg write_zero_string_args[2]; static const RzCmdDescArg write_from_io_args[3]; static const RzCmdDescArg write_from_io_xchg_args[3]; static const RzCmdDescArg write_from_file_args[4]; static const RzCmdDescArg write_from_socket_args[3]; +static const RzCmdDescArg write_wide_string_args[2]; static const RzCmdDescArg write_hex_args[2]; static const RzCmdDescArg write_hex_from_file_args[2]; static const RzCmdDescArg write_assembly_args[2]; @@ -487,6 +492,22 @@ static const RzCmdDescArg write_assembly_inside_args[2]; static const RzCmdDescArg write_assembly_file_args[2]; static const RzCmdDescArg write_assembly_opcode_args[2]; static const RzCmdDescArg write_block_args[2]; +static const RzCmdDescArg write_mask_set_args[2]; +static const RzCmdDescArg write_op_add_args[2]; +static const RzCmdDescArg write_op_and_args[2]; +static const RzCmdDescArg write_op_div_args[2]; +static const RzCmdDescArg write_op_shl_args[2]; +static const RzCmdDescArg write_op_mul_args[2]; +static const RzCmdDescArg write_op_or_args[2]; +static const RzCmdDescArg write_op_shr_args[2]; +static const RzCmdDescArg write_op_sub_args[2]; +static const RzCmdDescArg write_op_xor_args[2]; +static const RzCmdDescArg write_op_sequence_args[5]; +static const RzCmdDescArg write_op_decrypt_args[4]; +static const RzCmdDescArg write_op_encrypt_args[4]; +static const RzCmdDescArg write_debruijn_args[2]; +static const RzCmdDescArg write_debruijn_find_args[2]; +static const RzCmdDescArg write_duplicate_args[3]; static const RzCmdDescArg write_length_string_args[2]; static const RzCmdDescArg yank_args[2]; static const RzCmdDescArg yank_file_args[3]; @@ -10518,8 +10539,17 @@ static const RzCmdDescHelp write_extend_hexbytes_help = { .args = write_extend_hexbytes_args, }; -static const RzCmdDescHelp wu_handler_old_help = { +static const RzCmdDescArg write_unified_patch_args[] = { + { + .name = "file", + .type = RZ_CMD_ARG_TYPE_FILE, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_unified_patch_help = { .summary = "Apply unified hex patch (see output of cu)", + .args = write_unified_patch_args, }; static const RzCmdDescArg write_random_args[] = { @@ -10632,12 +10662,18 @@ static const RzCmdDescHelp write_pcache_commit_help = { .args = write_pcache_commit_args, }; -static const RzCmdDescHelp wz_handler_old_help = { - .summary = "Write zero-terminated string", -}; +static const RzCmdDescArg write_zero_string_args[] = { + { + .name = "string", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, -static const RzCmdDescHelp wt_handler_old_help = { - .summary = "Write to file", + }, + { 0 }, +}; +static const RzCmdDescHelp write_zero_string_help = { + .summary = "Write zero-terminated string", + .args = write_zero_string_args, }; static const RzCmdDescHelp wf_help = { @@ -10727,8 +10763,18 @@ static const RzCmdDescHelp write_from_socket_help = { .args = write_from_socket_args, }; -static const RzCmdDescHelp ww_handler_old_help = { +static const RzCmdDescArg write_wide_string_args[] = { + { + .name = "string", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_wide_string_help = { .summary = "Write wide 16 little endian string", + .args = write_wide_string_args, }; static const RzCmdDescHelp wx_help = { @@ -10854,16 +10900,338 @@ static const RzCmdDescHelp write_block_help = { .args = write_block_args, }; -static const RzCmdDescHelp wm_handler_old_help = { +static const RzCmdDescHelp wm_help = { .summary = "Set binary mask hexpair to be used as cyclic write mask", }; +static const RzCmdDescArg write_mask_set_args[] = { + { + .name = "hex_mask", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, -static const RzCmdDescHelp wo_handler_old_help = { - .summary = "Write in block with operation", + }, + { 0 }, +}; +static const RzCmdDescHelp write_mask_set_help = { + .summary = "Set a write mask", + .description = "Set a write mask that is applied whenever a following write operation is performed. Data will be masked as if the first byte of data is in arithmetic AND (&) with the first byte of the mask, the second byte of data with the second byte of the mask, and so on.", + .args = write_mask_set_args, }; -static const RzCmdDescHelp wd_handler_old_help = { - .summary = "Duplicate N bytes from offset at current seek", +static const RzCmdDescArg write_mask_reset_args[] = { + { 0 }, +}; +static const RzCmdDescHelp write_mask_reset_help = { + .summary = "Remove the write mask", + .args = write_mask_reset_args, +}; + +static const RzCmdDescDetailEntry wo_Examples_detail_entries[] = { + { .text = "woa", .arg_str = " 20", .comment = "Content before: 1122334455 ; Content after: 3142536475" }, + { .text = "wos", .arg_str = " 2021", .comment = "Content before: 1122334455 ; Content after: f101132335" }, + { .text = "wo4", .arg_str = "", .comment = "Content before: 1122334455667788; Content after: 4433221188776655" }, + { 0 }, +}; +static const RzCmdDescDetail wo_details[] = { + { .name = "Examples", .entries = wo_Examples_detail_entries }, + { 0 }, +}; +static const RzCmdDescHelp wo_help = { + .summary = "Write a block with a special operation", + .details = wo_details, +}; +static const RzCmdDescArg write_op_2byteswap_args[] = { + { 0 }, +}; +static const RzCmdDescHelp write_op_2byteswap_help = { + .summary = "Swap the endianess of 2-bytes values in the current block", + .args = write_op_2byteswap_args, +}; + +static const RzCmdDescArg write_op_4byteswap_args[] = { + { 0 }, +}; +static const RzCmdDescHelp write_op_4byteswap_help = { + .summary = "Swap the endianess of 4-bytes values in the current block", + .args = write_op_4byteswap_args, +}; + +static const RzCmdDescArg write_op_8byteswap_args[] = { + { 0 }, +}; +static const RzCmdDescHelp write_op_8byteswap_help = { + .summary = "Swap the endianess of 8-bytes values in the current block", + .args = write_op_8byteswap_args, +}; + +static const RzCmdDescArg write_op_add_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_add_help = { + .summary = "Add each existing byte in the block with the given ", + .args = write_op_add_args, +}; + +static const RzCmdDescArg write_op_and_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_and_help = { + .summary = "Bitwise-and each existing byte in the block with the given ", + .args = write_op_and_args, +}; + +static const RzCmdDescArg write_op_div_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_div_help = { + .summary = "Divide each existing byte in the block with the given ", + .args = write_op_div_args, +}; + +static const RzCmdDescArg write_op_shl_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_shl_help = { + .summary = "Bitwise-shift-left each existing byte in the block with the given ", + .args = write_op_shl_args, +}; + +static const RzCmdDescArg write_op_mul_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_mul_help = { + .summary = "Multiply each existing byte in the block with the given ", + .args = write_op_mul_args, +}; + +static const RzCmdDescArg write_op_or_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_or_help = { + .summary = "Bitwise-or each existing byte in the block with the given ", + .args = write_op_or_args, +}; + +static const RzCmdDescArg write_op_shr_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_shr_help = { + .summary = "Bitwise-shift-right each existing byte in the block with the given ", + .args = write_op_shr_args, +}; + +static const RzCmdDescArg write_op_sub_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_sub_help = { + .summary = "Subtract each existing byte in the block with the given ", + .args = write_op_sub_args, +}; + +static const RzCmdDescArg write_op_xor_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_xor_help = { + .summary = "Bitwise-xor each existing byte in the block with the given ", + .args = write_op_xor_args, +}; + +static const RzCmdDescDetailEntry write_op_sequence_Examples_detail_entries[] = { + { .text = "woe", .arg_str = " 1 3 1", .comment = "Write 010203010203010203" }, + { .text = "woe", .arg_str = " 1 4 2", .comment = "Write 010301030103010301" }, + { .text = "woe", .arg_str = " 1 5 2", .comment = "Write 010305020401030502" }, + { .text = "woe", .arg_str = " 1 3 1 2", .comment = "Write 01000200030001000200" }, + { 0 }, +}; +static const RzCmdDescDetail write_op_sequence_details[] = { + { .name = "Examples", .entries = write_op_sequence_Examples_detail_entries }, + { 0 }, +}; +static const RzCmdDescArg write_op_sequence_args[] = { + { + .name = "from", + .type = RZ_CMD_ARG_TYPE_NUM, + + }, + { + .name = "to", + .type = RZ_CMD_ARG_TYPE_NUM, + + }, + { + .name = "step", + .type = RZ_CMD_ARG_TYPE_NUM, + .default_value = "1", + + }, + { + .name = "value_size", + .type = RZ_CMD_ARG_TYPE_NUM, + .default_value = "1", + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_sequence_help = { + .summary = "Write a sequence repeatedly with values from up to in the block", + .description = "Write a sequence of data to fill the whole block at the current offset. The sequence is formed starting from up to , with an increment specified in . Each value is written as a -bytes value, according to the endianess specified in cfg.bigendian.", + .details = write_op_sequence_details, + .args = write_op_sequence_args, +}; + +static const RzCmdDescArg write_op_decrypt_args[] = { + { + .name = "algo", + .type = RZ_CMD_ARG_TYPE_STRING, + + }, + { + .name = "key", + .type = RZ_CMD_ARG_TYPE_STRING, + + }, + { + .name = "IV", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_decrypt_help = { + .summary = "Decrypt current block with given , and optional ", + .args = write_op_decrypt_args, +}; + +static const RzCmdDescArg write_op_encrypt_args[] = { + { + .name = "algo", + .type = RZ_CMD_ARG_TYPE_STRING, + + }, + { + .name = "key", + .type = RZ_CMD_ARG_TYPE_STRING, + + }, + { + .name = "IV", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_op_encrypt_help = { + .summary = "Encrypt current block with given , and optional ", + .args = write_op_encrypt_args, +}; + +static const RzCmdDescHelp wD_help = { + .summary = "Write De Bruijn Pattern", +}; +static const RzCmdDescArg write_debruijn_args[] = { + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_debruijn_help = { + .summary = "Write a De Bruijn Pattern of length at the current offset", + .args = write_debruijn_args, +}; + +static const RzCmdDescArg write_debruijn_find_args[] = { + { + .name = "value", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_debruijn_find_help = { + .summary = "Returns the offset where can be found in a De Bruijn Pattern", + .description = "It search for a particular value in the pattern as returned by the `wD` command. is assumed to be a number of as few bytes as necessary, in the endian specified by cfg.bigendian.", + .args = write_debruijn_find_args, +}; + +static const RzCmdDescArg write_duplicate_args[] = { + { + .name = "src", + .type = RZ_CMD_ARG_TYPE_RZNUM, + + }, + { + .name = "len", + .type = RZ_CMD_ARG_TYPE_RZNUM, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp write_duplicate_help = { + .summary = "Duplicate bytes from offset to current seek", + .args = write_duplicate_args, }; static const RzCmdDescArg write_length_string_args[] = { @@ -14144,8 +14512,8 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *write_extend_hexbytes_cd = rz_cmd_desc_argv_new(core->rcmd, we_cd, "wex", rz_write_extend_hexbytes_handler, &write_extend_hexbytes_help); rz_warn_if_fail(write_extend_hexbytes_cd); - RzCmdDesc *wu_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wu", rz_wu_handler_old, &wu_handler_old_help); - rz_warn_if_fail(wu_handler_old_cd); + RzCmdDesc *write_unified_patch_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "wu", rz_write_unified_patch_handler, &write_unified_patch_help); + rz_warn_if_fail(write_unified_patch_cd); RzCmdDesc *write_random_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "wr", rz_write_random_handler, &write_random_help); rz_warn_if_fail(write_random_cd); @@ -14170,11 +14538,8 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *write_pcache_commit_cd = rz_cmd_desc_argv_new(core->rcmd, wc_cd, "wcpi", rz_write_pcache_commit_handler, &write_pcache_commit_help); rz_warn_if_fail(write_pcache_commit_cd); - RzCmdDesc *wz_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wz", rz_wz_handler_old, &wz_handler_old_help); - rz_warn_if_fail(wz_handler_old_cd); - - RzCmdDesc *wt_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wt", rz_wt_handler_old, &wt_handler_old_help); - rz_warn_if_fail(wt_handler_old_cd); + RzCmdDesc *write_zero_string_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "wz", rz_write_zero_string_handler, &write_zero_string_help); + rz_warn_if_fail(write_zero_string_cd); RzCmdDesc *wf_cd = rz_cmd_desc_group_new(core->rcmd, w_cd, "wf", rz_write_from_io_handler, &write_from_io_help, &wf_help); rz_warn_if_fail(wf_cd); @@ -14187,8 +14552,8 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *write_from_socket_cd = rz_cmd_desc_argv_new(core->rcmd, wf_cd, "wfs", rz_write_from_socket_handler, &write_from_socket_help); rz_warn_if_fail(write_from_socket_cd); - RzCmdDesc *ww_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "ww", rz_ww_handler_old, &ww_handler_old_help); - rz_warn_if_fail(ww_handler_old_cd); + RzCmdDesc *write_wide_string_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "ww", rz_write_wide_string_handler, &write_wide_string_help); + rz_warn_if_fail(write_wide_string_cd); RzCmdDesc *wx_cd = rz_cmd_desc_group_new(core->rcmd, w_cd, "wx", rz_write_hex_handler, &write_hex_help, &wx_help); rz_warn_if_fail(wx_cd); @@ -14209,14 +14574,65 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *write_block_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "wb", rz_write_block_handler, &write_block_help); rz_warn_if_fail(write_block_cd); - RzCmdDesc *wm_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wm", rz_wm_handler_old, &wm_handler_old_help); - rz_warn_if_fail(wm_handler_old_cd); + RzCmdDesc *wm_cd = rz_cmd_desc_group_new(core->rcmd, w_cd, "wm", rz_write_mask_set_handler, &write_mask_set_help, &wm_help); + rz_warn_if_fail(wm_cd); + RzCmdDesc *write_mask_reset_cd = rz_cmd_desc_argv_new(core->rcmd, wm_cd, "wm-", rz_write_mask_reset_handler, &write_mask_reset_help); + rz_warn_if_fail(write_mask_reset_cd); - RzCmdDesc *wo_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wo", rz_wo_handler_old, &wo_handler_old_help); - rz_warn_if_fail(wo_handler_old_cd); + RzCmdDesc *wo_cd = rz_cmd_desc_group_new(core->rcmd, w_cd, "wo", NULL, NULL, &wo_help); + rz_warn_if_fail(wo_cd); + RzCmdDesc *write_op_2byteswap_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wo2", rz_write_op_2byteswap_handler, &write_op_2byteswap_help); + rz_warn_if_fail(write_op_2byteswap_cd); - RzCmdDesc *wd_handler_old_cd = rz_cmd_desc_oldinput_new(core->rcmd, w_cd, "wd", rz_wd_handler_old, &wd_handler_old_help); - rz_warn_if_fail(wd_handler_old_cd); + RzCmdDesc *write_op_4byteswap_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wo4", rz_write_op_4byteswap_handler, &write_op_4byteswap_help); + rz_warn_if_fail(write_op_4byteswap_cd); + + RzCmdDesc *write_op_8byteswap_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wo8", rz_write_op_8byteswap_handler, &write_op_8byteswap_help); + rz_warn_if_fail(write_op_8byteswap_cd); + + RzCmdDesc *write_op_add_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woa", rz_write_op_add_handler, &write_op_add_help); + rz_warn_if_fail(write_op_add_cd); + + RzCmdDesc *write_op_and_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woA", rz_write_op_and_handler, &write_op_and_help); + rz_warn_if_fail(write_op_and_cd); + + RzCmdDesc *write_op_div_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wod", rz_write_op_div_handler, &write_op_div_help); + rz_warn_if_fail(write_op_div_cd); + + RzCmdDesc *write_op_shl_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wol", rz_write_op_shl_handler, &write_op_shl_help); + rz_warn_if_fail(write_op_shl_cd); + + RzCmdDesc *write_op_mul_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wom", rz_write_op_mul_handler, &write_op_mul_help); + rz_warn_if_fail(write_op_mul_cd); + + RzCmdDesc *write_op_or_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woo", rz_write_op_or_handler, &write_op_or_help); + rz_warn_if_fail(write_op_or_cd); + + RzCmdDesc *write_op_shr_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wor", rz_write_op_shr_handler, &write_op_shr_help); + rz_warn_if_fail(write_op_shr_cd); + + RzCmdDesc *write_op_sub_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wos", rz_write_op_sub_handler, &write_op_sub_help); + rz_warn_if_fail(write_op_sub_cd); + + RzCmdDesc *write_op_xor_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "wox", rz_write_op_xor_handler, &write_op_xor_help); + rz_warn_if_fail(write_op_xor_cd); + + RzCmdDesc *write_op_sequence_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woe", rz_write_op_sequence_handler, &write_op_sequence_help); + rz_warn_if_fail(write_op_sequence_cd); + + RzCmdDesc *write_op_decrypt_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woD", rz_write_op_decrypt_handler, &write_op_decrypt_help); + rz_warn_if_fail(write_op_decrypt_cd); + + RzCmdDesc *write_op_encrypt_cd = rz_cmd_desc_argv_new(core->rcmd, wo_cd, "woE", rz_write_op_encrypt_handler, &write_op_encrypt_help); + rz_warn_if_fail(write_op_encrypt_cd); + + RzCmdDesc *wD_cd = rz_cmd_desc_group_new(core->rcmd, w_cd, "wD", rz_write_debruijn_handler, &write_debruijn_help, &wD_help); + rz_warn_if_fail(wD_cd); + RzCmdDesc *write_debruijn_find_cd = rz_cmd_desc_argv_new(core->rcmd, wD_cd, "wD/", rz_write_debruijn_find_handler, &write_debruijn_find_help); + rz_warn_if_fail(write_debruijn_find_cd); + + RzCmdDesc *write_duplicate_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "wd", rz_write_duplicate_handler, &write_duplicate_help); + rz_warn_if_fail(write_duplicate_cd); RzCmdDesc *write_length_string_cd = rz_cmd_desc_argv_new(core->rcmd, w_cd, "ws", rz_write_length_string_handler, &write_length_string_help); rz_warn_if_fail(write_length_string_cd); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 433e36e830..35e8e714a9 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -749,7 +749,7 @@ RZ_IPI RzCmdStatus rz_write_base64_encode_handler(RzCore *core, int argc, const RZ_IPI RzCmdStatus rz_write_extend_zero_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_extend_shift_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_extend_hexbytes_handler(RzCore *core, int argc, const char **argv); -RZ_IPI int rz_wu_handler_old(void *data, const char *input); +RZ_IPI RzCmdStatus rz_write_unified_patch_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_random_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_cache_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); RZ_IPI RzCmdStatus rz_write_cache_remove_handler(RzCore *core, int argc, const char **argv); @@ -758,13 +758,12 @@ RZ_IPI RzCmdStatus rz_write_cache_commit_handler(RzCore *core, int argc, const c RZ_IPI RzCmdStatus rz_write_cache_commit_all_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_pcache_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); RZ_IPI RzCmdStatus rz_write_pcache_commit_handler(RzCore *core, int argc, const char **argv); -RZ_IPI int rz_wz_handler_old(void *data, const char *input); -RZ_IPI int rz_wt_handler_old(void *data, const char *input); +RZ_IPI RzCmdStatus rz_write_zero_string_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_from_io_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_from_io_xchg_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_from_file_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_from_socket_handler(RzCore *core, int argc, const char **argv); -RZ_IPI int rz_ww_handler_old(void *data, const char *input); +RZ_IPI RzCmdStatus rz_write_wide_string_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_hex_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_hex_from_file_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_assembly_handler(RzCore *core, int argc, const char **argv); @@ -772,9 +771,26 @@ RZ_IPI RzCmdStatus rz_write_assembly_inside_handler(RzCore *core, int argc, cons RZ_IPI RzCmdStatus rz_write_assembly_file_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_assembly_opcode_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_block_handler(RzCore *core, int argc, const char **argv); -RZ_IPI int rz_wm_handler_old(void *data, const char *input); -RZ_IPI int rz_wo_handler_old(void *data, const char *input); -RZ_IPI int rz_wd_handler_old(void *data, const char *input); +RZ_IPI RzCmdStatus rz_write_mask_set_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_mask_reset_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_2byteswap_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_4byteswap_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_8byteswap_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_add_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_and_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_div_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_shl_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_mul_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_or_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_shr_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_sub_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_xor_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_sequence_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_decrypt_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_op_encrypt_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_debruijn_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_debruijn_find_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_write_duplicate_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_write_length_string_handler(RzCore *core, int argc, const char **argv); RZ_IPI int rz_cmd_hexdump(void *data, const char *input); RZ_IPI RzCmdStatus rz_yank_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); diff --git a/librz/core/cmd_descs/cmd_write.yaml b/librz/core/cmd_descs/cmd_write.yaml index 3de8ffc553..3c7fa93020 100644 --- a/librz/core/cmd_descs/cmd_write.yaml +++ b/librz/core/cmd_descs/cmd_write.yaml @@ -301,9 +301,11 @@ commands: arg_str: " 414243" comment: Insert the characters "ABC" at the current offset and extend the file - name: wu - cname: wu_handler_old + cname: write_unified_patch summary: Apply unified hex patch (see output of cu) - type: RZ_CMD_DESC_TYPE_OLDINPUT + args: + - name: file + type: RZ_CMD_ARG_TYPE_FILE - name: wr cname: write_random summary: Write random bytes @@ -368,13 +370,11 @@ commands: type: RZ_CMD_ARG_TYPE_NUM optional: true - name: wz - cname: wz_handler_old + cname: write_zero_string summary: Write zero-terminated string - type: RZ_CMD_DESC_TYPE_OLDINPUT - - name: wt - cname: wt_handler_old - summary: Write to file - type: RZ_CMD_DESC_TYPE_OLDINPUT + args: + - name: string + type: RZ_CMD_ARG_TYPE_STRING - name: wf summary: Write data from file, socket, offset subcommands: @@ -416,9 +416,11 @@ commands: type: RZ_CMD_ARG_TYPE_RZNUM optional: true - name: ww - cname: ww_handler_old + cname: write_wide_string summary: Write wide 16 little endian string - type: RZ_CMD_DESC_TYPE_OLDINPUT + args: + - name: string + type: RZ_CMD_ARG_TYPE_STRING - name: wx summary: Write hexadecimal data subcommands: @@ -516,17 +518,188 @@ commands: - name: hex type: RZ_CMD_ARG_TYPE_STRING - name: wm - cname: wm_handler_old summary: Set binary mask hexpair to be used as cyclic write mask - type: RZ_CMD_DESC_TYPE_OLDINPUT + subcommands: + - name: wm + cname: write_mask_set + summary: Set a write mask + description: > + Set a write mask that is applied whenever a following write operation + is performed. Data will be masked as if the first byte of data is in + arithmetic AND (&) with the first byte of the mask, the second byte of + data with the second byte of the mask, and so on. + args: + - name: hex_mask + type: RZ_CMD_ARG_TYPE_STRING + - name: wm- + cname: write_mask_reset + summary: Remove the write mask + args: [] - name: wo - cname: wo_handler_old - summary: Write in block with operation - type: RZ_CMD_DESC_TYPE_OLDINPUT + summary: Write a block with a special operation + subcommands: + - name: wo2 + cname: write_op_2byteswap + summary: Swap the endianess of 2-bytes values in the current block + args: [] + - name: wo4 + cname: write_op_4byteswap + summary: Swap the endianess of 4-bytes values in the current block + args: [] + - name: wo8 + cname: write_op_8byteswap + summary: Swap the endianess of 8-bytes values in the current block + args: [] + - name: woa + cname: write_op_add + summary: Add each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: woA + cname: write_op_and + summary: Bitwise-and each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wod + cname: write_op_div + summary: Divide each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wol + cname: write_op_shl + summary: Bitwise-shift-left each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wom + cname: write_op_mul + summary: Multiply each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: woo + cname: write_op_or + summary: Bitwise-or each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wor + cname: write_op_shr + summary: Bitwise-shift-right each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wos + cname: write_op_sub + summary: Subtract each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wox + cname: write_op_xor + summary: Bitwise-xor each existing byte in the block with the given + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM + - name: woe + cname: write_op_sequence + summary: Write a sequence repeatedly with values from up to in the block + description: > + Write a sequence of data to fill the whole block at the current + offset. The sequence is formed starting from up to , with + an increment specified in . Each value is written as a + -bytes value, according to the endianess specified in + cfg.bigendian. + args: + - name: from + type: RZ_CMD_ARG_TYPE_NUM + - name: to + type: RZ_CMD_ARG_TYPE_NUM + - name: step + type: RZ_CMD_ARG_TYPE_NUM + default_value: 1 + - name: value_size + type: RZ_CMD_ARG_TYPE_NUM + default_value: 1 + details: + - name: Examples + entries: + - text: woe + arg_str: " 1 3 1" + comment: "Write 010203010203010203" + - text: woe + arg_str: " 1 4 2" + comment: "Write 010301030103010301" + - text: woe + arg_str: " 1 5 2" + comment: "Write 010305020401030502" + - text: woe + arg_str: " 1 3 1 2" + comment: "Write 01000200030001000200" + - name: woD + cname: write_op_decrypt + summary: Decrypt current block with given , and optional + args: + - name: algo + type: RZ_CMD_ARG_TYPE_STRING + - name: key + type: RZ_CMD_ARG_TYPE_STRING + - name: IV + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: woE + cname: write_op_encrypt + summary: Encrypt current block with given , and optional + args: + - name: algo + type: RZ_CMD_ARG_TYPE_STRING + - name: key + type: RZ_CMD_ARG_TYPE_STRING + - name: IV + type: RZ_CMD_ARG_TYPE_STRING + optional: true + details: + - name: Examples + entries: + - text: woa + arg_str: " 20" + comment: "Content before: 1122334455 ; Content after: 3142536475" + - text: wos + arg_str: " 2021" + comment: "Content before: 1122334455 ; Content after: f101132335" + - text: wo4 + arg_str: "" + comment: "Content before: 1122334455667788; Content after: 4433221188776655" + - name: wD + summary: Write De Bruijn Pattern + subcommands: + - name: wD + cname: write_debruijn + summary: Write a De Bruijn Pattern of length at the current offset + args: + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM + - name: wD/ + cname: write_debruijn_find + summary: Returns the offset where can be found in a De Bruijn Pattern + description: > + It search for a particular value in the pattern as returned by the + `wD` command. is assumed to be a number of as few bytes as + necessary, in the endian specified by cfg.bigendian. + args: + - name: value + type: RZ_CMD_ARG_TYPE_RZNUM - name: wd - cname: wd_handler_old - summary: Duplicate N bytes from offset at current seek - type: RZ_CMD_DESC_TYPE_OLDINPUT + summary: Duplicate bytes from offset to current seek + cname: write_duplicate + args: + - name: src + type: RZ_CMD_ARG_TYPE_RZNUM + - name: len + type: RZ_CMD_ARG_TYPE_RZNUM - name: ws cname: write_length_string summary: Write 1 byte for length and then the string diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 993cf95726..624f630a43 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -103,6 +103,21 @@ typedef enum { RZ_CORE_VISUAL_MODE_CD = 4 ///< Print in string format } RzCoreVisualMode; +typedef enum { + RZ_CORE_WRITE_OP_BYTESWAP2, ///< Swap the endianess of 2-bytes values + RZ_CORE_WRITE_OP_BYTESWAP4, ///< Swap the endianess of 4-bytes values + RZ_CORE_WRITE_OP_BYTESWAP8, ///< Swap the endianess of 8-bytes values + RZ_CORE_WRITE_OP_ADD, ///< Write the addition of existing byte and argument value + RZ_CORE_WRITE_OP_SUB, ///< Write the subtraction of existing byte and argument value + RZ_CORE_WRITE_OP_DIV, ///< Write the division of existing byte and argument value + RZ_CORE_WRITE_OP_MUL, ///< Write the multiplication of existing byte and argument value + RZ_CORE_WRITE_OP_AND, ///< Write the bitwise-and of existing byte and argument value + RZ_CORE_WRITE_OP_OR, ///< Write the bitwise-or of existing byte and argument value + RZ_CORE_WRITE_OP_XOR, ///< Write the bitwise-xor of existing byte and argument value + RZ_CORE_WRITE_OP_SHIFT_LEFT, ///< Write the shift left of existing byte by argument value + RZ_CORE_WRITE_OP_SHIFT_RIGHT, ///< Write the shift right of existing byte and argument value +} RzCoreWriteOp; + typedef bool (*RzCorePluginInit)(RzCore *core); typedef bool (*RzCorePluginFini)(RzCore *core); @@ -498,6 +513,7 @@ RZ_API int rz_core_write_hexpair(RzCore *core, ut64 addr, const char *pairs); RZ_API int rz_core_write_assembly(RzCore *core, ut64 addr, RZ_NONNULL const char *instructions); RZ_API int rz_core_write_assembly_fill(RzCore *core, ut64 addr, RZ_NONNULL const char *instructions); RZ_API bool rz_core_write_block(RzCore *core, ut64 addr, ut8 *data, size_t len); +RZ_API bool rz_core_write_seq_at(RzCore *core, ut64 addr, ut64 from, ut64 to, ut64 step, int value_size); RZ_API bool rz_core_shift_block(RzCore *core, ut64 addr, ut64 b_size, st64 dist); RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf, RzLinePromptType prompt_type); RZ_API RzLineNSCompletionResult *rz_core_autocomplete_rzshell(RzCore *core, RzLineBuffer *buf, RzLinePromptType prompt_type); @@ -586,12 +602,14 @@ RZ_API bool rz_core_write_at(RzCore *core, ut64 addr, const ut8 *buf, int size); RZ_API bool rz_core_write_value_at(RzCore *core, ut64 addr, ut64 value, int sz); RZ_API bool rz_core_write_value_inc_at(RzCore *core, ut64 addr, st64 value, int sz); RZ_API bool rz_core_write_string_at(RzCore *core, ut64 addr, RZ_NONNULL const char *s); +RZ_API bool rz_core_write_string_zero_at(RzCore *core, ut64 addr, const char *s); +RZ_API bool rz_core_write_string_wide_at(RzCore *core, ut64 addr, const char *s); RZ_API bool rz_core_write_length_string_at(RzCore *core, ut64 addr, const char *s); RZ_API bool rz_core_write_base64d_at(RzCore *core, ut64 addr, RZ_NONNULL const char *s); RZ_API bool rz_core_write_base64_at(RzCore *core, ut64 addr, RZ_NONNULL const char *s); RZ_API bool rz_core_write_random_at(RzCore *core, ut64 addr, size_t len); -RZ_API int rz_core_write_op(RzCore *core, const char *arg, char op); -RZ_API ut8 *rz_core_transform_op(RzCore *core, const char *arg, char op); +RZ_API bool rz_core_write_block_op_at(RzCore *core, ut64 addr, RzCoreWriteOp op, ut8 *hex, int hexlen); +RZ_API ut8 *rz_core_transform_op(RzCore *core, ut64 addr, RzCoreWriteOp op, ut8 *hex, int hexlen, int *buflen); RZ_API ut32 rz_core_file_cur_fd(RzCore *core); RZ_API RzCmdStatus rz_core_io_cache_print(RzCore *core, RzCmdStateOutput *state); RZ_API RzCmdStatus rz_core_io_pcache_print(RzCore *core, RzIODesc *desc, RzCmdStateOutput *state); diff --git a/librz/include/rz_util/rz_debruijn.h b/librz/include/rz_util/rz_debruijn.h index 263800d8ab..1b3f8093b3 100644 --- a/librz/include/rz_util/rz_debruijn.h +++ b/librz/include/rz_util/rz_debruijn.h @@ -13,14 +13,8 @@ extern "C" { // For information about the algorithm, see Joe Sawada and Frank Ruskey, "An // Efficient Algorithm for Generating Necklaces with Fixed Density" -// Generate a cyclic pattern of desired size, and charset, return with starting -// offset of start. -// The returned string is malloced, and it is the responsibility of the caller -// to free the memory. RZ_API char *rz_debruijn_pattern(int size, int start, const char *charset); - -// Finds the offset of a given value in a cyclic pattern of an integer. -RZ_API int rz_debruijn_offset(ut64 value, bool is_big_endian); +RZ_API int rz_debruijn_offset(int start, const char *charset, ut64 value, bool is_big_endian); #ifdef __cplusplus } diff --git a/librz/io/io.c b/librz/io/io.c index 89d0b9d1da..419f2b3099 100644 --- a/librz/io/io.c +++ b/librz/io/io.c @@ -505,10 +505,18 @@ RZ_API bool rz_io_extend_at(RzIO *io, ut64 addr, ut64 size) { #undef IO_EXTEND_BLOCK_SZ } +/** + * \brief Set a mask that is used on all following write operations + * + * \param io Reference to RzIo instance + * \param mask Mask to apply + * \param len Number of bytes in the mask + * \return true if the mask was correctly set, false otherwise + */ RZ_API bool rz_io_set_write_mask(RzIO *io, const ut8 *mask, int len) { - if (!io || len < 1) { - return false; - } + rz_return_val_if_fail(io, false); + rz_return_val_if_fail(mask || len == 0, false); + free(io->write_mask); if (!mask) { io->write_mask = NULL; diff --git a/librz/main/rz-gg.c b/librz/main/rz-gg.c index 4679777d3e..3f8307e1c8 100644 --- a/librz/main/rz-gg.c +++ b/librz/main/rz-gg.c @@ -349,8 +349,8 @@ RZ_API int rz_main_rz_gg(int argc, const char **argv) { } get_offset = rz_num_math(0, sequence); - printf("Little endian: %d\n", rz_debruijn_offset(get_offset, false)); - printf("Big endian: %d\n", rz_debruijn_offset(get_offset, true)); + printf("Little endian: %d\n", rz_debruijn_offset(0, NULL, get_offset, false)); + printf("Big endian: %d\n", rz_debruijn_offset(0, NULL, get_offset, true)); free(sequence); rz_egg_free(egg); return 0; diff --git a/librz/util/debruijn.c b/librz/util/debruijn.c index cfba39f571..62fa84741f 100644 --- a/librz/util/debruijn.c +++ b/librz/util/debruijn.c @@ -63,78 +63,82 @@ static char *de_bruijn(const char *charset, int order, int maxlen) { return sequence; } -// Generate a cyclic pattern of desired size, and charset, return with starting -// offset of start. -// The returned string is malloced, and it is the responsibility of the caller -// to free the memory. -RZ_API char *rz_debruijn_pattern(int size, int start, const char *charset) { - char *pat, *pat2; - ut64 len; +/** + * \brief Generate a cyclic pattern following the Debruijn pattern + * + * Generate a cyclic pattern of desired size, and charset, return with starting + * offset of start. + * + * For example, AAABAACAAD is a sequence of size 10, start 0, charset = + * debruijn_charset. + * + * \param size Size of the string to return + * \param start Starting offset in the Debruijn pattern + * \param charset Set of characters to use to generate the string + * \return String of length \p size allocated on the heap + */ +RZ_API RZ_OWN char *rz_debruijn_pattern(int size, int start, const char *charset) { + rz_return_val_if_fail(size >= 0, NULL); + rz_return_val_if_fail(start >= 0, NULL); if (!charset) { charset = debruijn_charset; } - if (start >= size) { - return (char *)NULL; - } - pat = de_bruijn(charset, 3 /*subsequence length*/, size); - if (!pat) { - return NULL; - } - if (start == 0) { - len = strlen(pat); - if (size != len) { - eprintf("warning: requested pattern of length %d, " - "generated length %" PFMT64d "\n", - size, len); - } + char *pat = de_bruijn(charset, 3, size + start); + if (!pat || start == 0) { return pat; } - pat2 = calloc((size - start) + 1, sizeof(char)); + + char *pat2 = RZ_NEWS0(char, size + 1); if (!pat2) { free(pat); return NULL; } - strncpy(pat2, pat + start, size - start); - pat2[size - start] = 0; + size_t len = strlen(pat + start); + rz_return_val_if_fail(len <= size, NULL); + strcpy(pat2, pat + start); free(pat); - len = strlen(pat2); - if (size != len) { - eprintf("warning: requested pattern of length %d, " - "generated length %" PFMT64d "\n", - size, len); - } return pat2; } -// Finds the offset of a given value in a cyclic pattern of an integer. -RZ_API int rz_debruijn_offset(ut64 value, bool is_big_endian) { - char *needle, *pattern, buf[9]; +/** + * \brief Finds the offset of a given value in a debrujn sequence + * + * \param start Starting offset in the Debruijn pattern + * \param charset Set of characters to use to generate the sequence + * \param value Value to search in the sequence + * \param is_big_endian Endianess of \p value + * \return The offset in the sequence where \p value is found or -1 if not found + */ +RZ_API int rz_debruijn_offset(int start, const char *charset, ut64 value, bool is_big_endian) { int retval = -1; - char *pch; // 0x10000 should be long enough. This is how peda works, and nobody complains // ... but is slow. Optimize for common case. - int lens[2] = { 0x1000, 0x10000 }; + int lens[] = { 0x1000, 0x10000, 0x100000 }; int j; if (value == 0) { return -1; } - for (j = 0; j < 2 && retval == -1; j++) { - pattern = rz_debruijn_pattern(lens[j], 0, debruijn_charset); + for (j = 0; j < RZ_ARRAY_SIZE(lens) && retval == -1; j++) { + char *pattern = rz_debruijn_pattern(lens[j], start, charset); + if (!pattern) { + return -1; + } + char buf[9]; buf[8] = '\0'; if (is_big_endian) { rz_write_be64(buf, value); } else { rz_write_le64(buf, value); } + char *needle; for (needle = buf; !*needle; needle++) { /* do nothing here */ } - pch = strstr(pattern, needle); - + char *pch = strstr(pattern, needle); if (pch) { retval = (int)(size_t)(pch - pattern); } diff --git a/test/db/archos/darwin-x64/cmd_i b/test/db/archos/darwin-x64/cmd_i index eb858dd1ca..be0fdf0679 100644 --- a/test/db/archos/darwin-x64/cmd_i +++ b/test/db/archos/darwin-x64/cmd_i @@ -4,7 +4,7 @@ FILE== CMDS=< `prz`; o `prz`; i~file; ij; rm `prz`)" .(show_fname A\x1b¢\302\200€𝄞\363\240\201\201\\.bin) .(show_fname B\x1b¢\302\200€𝄞\363\240\201\201\\.bin) # INVALID FILENAME .(show_fname B\x1b¢\302\200\201€𝄞\363\240\201\201\\.bin) diff --git a/test/db/archos/linux-any/cmd_i b/test/db/archos/linux-any/cmd_i index 60ebd673d9..92ef4630dc 100644 --- a/test/db/archos/linux-any/cmd_i +++ b/test/db/archos/linux-any/cmd_i @@ -4,7 +4,7 @@ FILE== CMDS=< `prz` ; o `prz`; i~file; ij; rm `prz`)" .(show_fname A\x1b¢\302\200€𝄞\363\240\201\201\\.bin) .(show_fname B\x1b¢\302\200€𝄞\363\240\201\201\\.bin) .(show_fname B\x1b¢\302\200\201€𝄞\363\240\201\201\\.bin) diff --git a/test/db/cmd/cmd_pd b/test/db/cmd/cmd_pd index 845eaebada..a44ace9b05 100644 --- a/test/db/cmd/cmd_pd +++ b/test/db/cmd/cmd_pd @@ -1939,7 +1939,7 @@ e asm.arch=x86 e asm.bits=32 e asm.bytes=false s 0x1000 -"wz path\"C:\\Program\n" +wz "path\"C:\\Program\n" f ansi_str s 0x2000 wa "mov eax, 0x1000" @@ -1950,7 +1950,7 @@ e str.escbslash=false pd 1 pdJ 1 s 0x3000 -"ww path\"C:\\Program\r" +ww "path\"C:\\Program\r" f wide_str s 0x4000 wa "mov ebx, 0x3000" diff --git a/test/db/cmd/cmd_pf b/test/db/cmd/cmd_pf index 9c4efb98be..cb386687c1 100644 --- a/test/db/cmd/cmd_pf +++ b/test/db/cmd/cmd_pf @@ -2,7 +2,7 @@ NAME=pf QeQ FILE== CMDS=< .rz-wt.test p8 4 @ 4 wff .rz-wt.test @ 4 rm .rz-wt.test diff --git a/test/db/cmd/cmd_wop b/test/db/cmd/cmd_wD similarity index 82% rename from test/db/cmd/cmd_wop rename to test/db/cmd/cmd_wD index 3559902724..9ae1c638b0 100644 --- a/test/db/cmd/cmd_wop +++ b/test/db/cmd/cmd_wD @@ -2,7 +2,7 @@ NAME=debruijn little endian FILE== CMDS=< .p -.wu .p +wu .p !rm -f .p b 32 cu 16 diff --git a/test/db/cmd/write b/test/db/cmd/write index b36709c8ba..4b657ee7da 100644 --- a/test/db/cmd/write +++ b/test/db/cmd/write @@ -232,14 +232,11 @@ EXPECT=< a_piece_of_ls_saved_to_PWD ls -l a_piece_of_ls_saved_to_PWD~[3] rm a_piece_of_ls_saved_to_PWD EOF @@ -247,7 +244,7 @@ EXPECT=< /dev/null e io.va=true b 0x1000 -wow 20 @ 0x80000 +wb 0x20 @ 0x80000 b 20 p8 @ 0 p8 @ 90 diff --git a/test/db/io/omp b/test/db/io/omp index 330ea4ca41..fec7dbb171 100644 --- a/test/db/io/omp +++ b/test/db/io/omp @@ -48,7 +48,7 @@ NAME=omp 2 FILE=malloc://3 CMDS=< TRAINING..." @ 32700 -"wz RECEPCAO..." @ 32724 -"wz ERRO PROG RX" @ 32827 -"wz RECEBENDO DADOS..." @ 32840 -"wz TRAINING 4800..." @ 32874 -"wz TRAINING 2400..." @ 32891 -"wz TRAINING OK" @ 32908 -"wz ERRO TRAINING" @ 32920 -"wz FALHA:COMUNICACAO" @ 32968 -"wz ERRO BLOCO" @ 33016 -"wz CONTA OU DIGITO INCORRETO" @ 33027 -"wz CODIGO DA AGENCIA INCORRETO" @ 33053 -"wz DATA DO CARTAO DE CREDITO INCORRETA" @ 33081 -"wz 001002003005010011004020021022030031999040041042043N" @ 33164 -"wz xqke_ZUPLGC@<952/-*(&#! " @ 37772 -"wz #q#p#s#r#6" @ 38972 -"wz !&+05:?DINSX]bg" @ 39925 -"wz 3333333333333333333333333333" @ 42834 -"wz '()*+,-./012" @ 43375 -"wz 3456789:;<=>?@" @ 43401 -"wz IJKLMNOPQRST" @ 43455 -"wz ijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjk" @ 43535 -"wz lmmmmmmmmmmnopq" @ 43615 -"wz qstsssnnmmmmmmmmmmu" @ 43647 -"wz lmmmmmmmmmmvwxyz{|}~" @ 43695 -"wz wmmmmmmmmmu" @ 43743 -"wz lmmmᡭw±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ" @ 43935 -"wz lmÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåmu" @ 44015 -"wz lmæçèéêëìíîïðñòóôõö÷øùúæû" @ 44095 -"wz 'mmmmmmmmu" @ 44385 -"wz 'mmmmmmmmu" @ 44465 -"wz lmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmu" @ 44495 -"wz fffffffffa" @ 45590 -"wz faffffffffffa" @ 45687 -"wz ffffffffffff" @ 45806 -"wz fffffffffffaf" @ 45977 -"wz fafffafffafff" @ 46136 -"wz ffffffffffffffffffa" @ 46202 -"wz ffffffffffffffa" @ 46518 -"wz fffafffffa" @ 46574 -"wz fffffffffa" @ 46670 -"wz fffaffffff" @ 46689 -"wz ffafffafffa" @ 46841 -"wz ffafffafafffa" @ 46933 -"wz fafffafffa" @ 47072 -"wz fffffffffa" @ 47169 -"wz faffffffffffa" @ 47247 -"wz fafffafffa" @ 47440 -"wz fffafffffafff" @ 47534 -"wz ffffffffffffffff" @ 47598 -"wz afafffafffa" @ 47726 -"wz ffffffffffffa" @ 48177 -"wz fffffffffffaf" @ 48401 -"wz fafffafafaf" @ 48464 -"wz fafffafffa" @ 48527 -"wz ,-./0123456789:;<=543210/.-," @ 57312 -"wz >?@ABCDEFGHIJKLMNOPQQRSTULKJIHGFEDCBA@?>VWX" @ 57343 -"wz XVYZ[\\]^_`abccbadefgh[ZYVX" @ 57389 -"wz ijDkllmnoopqrstluultsvwxyz{|llkDji" @ 57424 -"wz CDEFGHIJKL*" @ 58042 -"wz MNOPQORSPT*" @ 58062 -"wz Z[\\]^_`abcdd9*" @ 58121 -"wz efghijklmnopqrstuvwxyz{|}~" @ 58150 -"wz '()*+,-./012" @ 58417 -"wz 3456789:;<=>?@" @ 58430 -"wz AB,CDEFGHIJKLMNOPQRST" @ 58445 -"wz QUVWXWYZ[\\]^_R" @ 58467 -"wz `abcdefghi!j" @ 58482 -"wz opqrstuvwxyz{|\tm" @ 58509 -"wz !\"#$%&'()*+,-./m0" @ 58758 -"wz 123456789:;<=46\tm" @ 58786 -"wz >??@?ABCDEFGH@AI\bm" @ 58811 -"wz 123456789:8;" @ 59128 -"wz #<=>?@ABC)(D\aEFGHIJKLMNOP" @ 59143 -"wz #QRSTUVWRXYZ" @ 59171 -"wz ()*+,-./012" @ 59553 -"wz 6789:;<=>?@ABCD" @ 59576 -"wz fghijklmno_^pqrstuvwxyHz" @ 59703 -"wz \"#$%&'()*+,-./0123\"" @ 59953 -"wz PWXYZ[\\]QNF^_`abO" @ 60055 -"wz PcdefghiQN" @ 60075 -"wz !\"#$%&'\"#$()*%+," @ 60267 -"wz #$%&'()*+,-./01234$" @ 60665 -"wz &'()*+,-./01" @ 61172 -"wz 23456789:;<=" @ 61186 -"wz >?@>ABCDEF@G" @ 61200 -"wz HIJKLJMNOPQR" @ 61214 -"wz STUVWUXYZ[\\]" @ 61228 -"wz '()*+,-./0" @ 61394 -"wz 234567891:" @ 61407 -"wz Df33D33JDf" @ 65002 -"wz Df33J433Df" @ 66042 -"wz Df33D3J3Df" @ 66065 -"wz Df334JDJ\b3" @ 66263 -"wz Df33J4J4Df" @ 67100 -"wz Df33D3J3Df33" @ 67124 -"wz Df33JDDJDf33" @ 67300 -"wz 3Df33J44JDf" @ 67315 -"wz Df33D34JDd" @ 68078 -"wz Df33J4D4Df" @ 68091 -"wz Df33J43DDf" @ 68133 -"wz Df33J4J3Df" @ 68194 -"wz 0\t9\t9\t9\t9\n" @ 89740 -"wz SUSU355355S53553" @ 91822 -"wz 5S5S3UU355U53" @ 92487 -"wz U3UU5SS3S3" @ 92515 -"wz wwwwwwwwwwwwwwww" @ 93824 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 93977 -"wz wwwqwwwqww" @ 94023 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 94287 -"wz wwwqwwwqwwwqwwww" @ 94329 -"wz wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 94360 -"wz wwwwwwwwwwwwwwwwwwwwwwqww" @ 94673 -"wz wwwwwwwwwww" @ 94709 -"wz wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 94726 -"wz wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 94760 -"wz qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 94824 -"wz wqwwwqwwww" @ 94928 -"wz wwqTwwqTww" @ 95004 -"wz DDAQDDDQDDDE" @ 95071 -"wz DDDQDDDEDDDDDDDDTDDD" @ 95084 -"wz DDEQDDQEDDQDDDE" @ 95164 -"wz TDUUDDDDDDDDDADDA" @ 95206 -"wz DDATDDATDD" @ 95263 -"wz DDDTDDEDDDQDDU" @ 95281 -"wz wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 95305 -"wz wwQwwwQwww" @ 95338 -"wz wwwwwwwwwwwwwwwwwwqwwq" @ 95349 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 95383 -"wz DDDEDDDDDDDDDDA" @ 95636 -"wz DDUUDDDDDDDDU" @ 95684 -"wz wwwwwwvwwwf" @ 97409 -"wz DDDTDDADDD" @ 97537 -"wz DEAQDEATDEATDE" @ 97550 -"wz DDQTDDQDDE" @ 97569 -"wz vfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvf" @ 97678 -"wz ffffffgvfgwffwvfgwvfgwffwwffwvffwvffwvffwvffwvffwvffwvffq" @ 97740 -"wz DDDEDDDDDDDDTDDD" @ 97868 -"wz DDDADDDDDDDDDDDDTDD" @ 97900 -"wz DDEQDDQEDDQDDDE" @ 97944 -"wz DDDDDDADDA" @ 97993 -"wz DDDTDDEDDDQDDU" @ 98061 -"wz wwwwwwwwwwwwwwqwwww" @ 98389 -"wz wwwwwwwwwwww" @ 98412 -"wz wwqwwwwwwwwwwwwwwwwwww" @ 98473 -"wz avafavafawafawqfawqff" @ 98519 -"wz wwqqwwqqwww" @ 98835 -"wz wwwqwwwqww" @ 98994 -"wz wwwwwwwwwwwwww" @ 99041 -"wz wwwwwwwwwwwwwwww" @ 99906 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 100059 -"wz wwwqwwwqww" @ 100105 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 100369 -"wz wwwqwwwqwwwqwwww" @ 100411 -"wz wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 100442 -"wz wwwwwwwwwwwwwwwwwwwwwwqww" @ 100755 -"wz wwwwwwwwwww" @ 100791 -"wz wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 100808 -"wz wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 100842 -"wz qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 100906 -"wz wqwwwqwwww" @ 101010 -"wz wwqTwwqTww" @ 101086 -"wz DDAQDDDQDDDE" @ 101153 -"wz DDDQDDDEDDDDDDDDTDDD" @ 101166 -"wz DDEQDDQEDDQDDDE" @ 101246 -"wz TDUUDDDDDDDDDADDA" @ 101288 -"wz DDATDDATDD" @ 101345 -"wz DDDTDDEDDDQDDU" @ 101363 -"wz wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 101387 -"wz wwQwwwQwww" @ 101420 -"wz wwwwwwwwwwwwwwwwwwqwwq" @ 101431 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 101465 -"wz DDDEDDDDDDDDDDA" @ 101718 -"wz DDUUDDDDDDDDU" @ 101766 -"wz wwwwwwvwwwf" @ 103487 -"wz DDDTDDADDD" @ 103615 -"wz DEAQDEATDEATDE" @ 103628 -"wz DDQTDDQDDE" @ 103647 -"wz vffwvffwvffwvffwvfgwvfgwvfwwvfwfffffgvfgwffwvffwvffwfffwfffvffafaTDf" @ 103723 -"wz DDDUDDDDDDDDTDDD" @ 103822 -"wz wvffwvffwvffwvffwvffwvffq" @ 104138 -"wz DDDADDDDDDDDDDDDTDD" @ 104202 -"wz wwwwwwwwwwwwwwqwwww" @ 104499 -"wz wwwwwwwwwwww" @ 104522 -"wz wwqwwwwwwwwwwwwwwwwwww" @ 104583 -"wz avafavafawafawqfawqff" @ 104629 -"wz wwqqwwqqwww" @ 104945 -"wz wwwqwwwqww" @ 105104 -"wz wwwwwwwwwwwwww" @ 105151 -"wz wwwwwwwwwwwwwwww" @ 106026 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 106179 -"wz wwwqwwwqww" @ 106225 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 106489 -"wz wwwqwwwqwwwqwwww" @ 106531 -"wz wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 106562 -"wz wwwwwwwwwwwwwwwwwwwwwwqww" @ 106875 -"wz wwwwwwwwwww" @ 106911 -"wz wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 106928 -"wz wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 106962 -"wz qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 107026 -"wz wqwwwqwwww" @ 107130 -"wz wwqTwwqTww" @ 107206 -"wz DDAQDDDQDDDE" @ 107273 -"wz DDDQDDDEDDDDDDDDTDDD" @ 107286 -"wz DDEQDDQEDDQDDDE" @ 107366 -"wz TDUUDDDDDDDDDADDA" @ 107408 -"wz DDATDDATDD" @ 107465 -"wz DDDTDDEDDDQDDU" @ 107483 -"wz wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 107507 -"wz wwQwwwQwww" @ 107540 -"wz wwwwwwwwwwwwwwwwwwqwwq" @ 107551 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 107585 -"wz DDDEDDDDDDDDDDA" @ 107838 -"wz DDUUDDDDDDDDU" @ 107886 -"wz wwwwwwvwwwf" @ 109649 -"wz DDDTDDADDD" @ 109777 -"wz DEAQDEATDEATDE" @ 109790 -"wz DDQTDDQDDE" @ 109809 -"wz vffwvffwvffwvffwvfgwvfgwvfwwvfwfffffgvfgwffwvffwvffwfffwfffvffafaTDf" @ 109885 -"wz DDDUDDDDDDDDTDDD" @ 109984 -"wz wvffwvffwvffwvffwvffwvffq" @ 110300 -"wz DDDADDDDDDDDDDDDTDD" @ 110364 -"wz wwwwwwwwwwwwwwqwwww" @ 110661 -"wz wwwwwwwwwwww" @ 110684 -"wz wwqwwwwwwwwwwwwwwwwwww" @ 110745 -"wz avafavafawafawqfawqff" @ 110791 -"wz qwqwqwqwqww" @ 111116 -"wz wwwwwwwwwwwwwww" @ 111260 -"wz wwwwwwwwwww" @ 111282 -"wz wwwwwwwwwwwwwwqwwwqwww" @ 111301 -"wz wwwqwwwwwwwwwwww" @ 111432 -"wz wwwwwwwwwwwwwww" @ 111449 -"wz wwwqwwwqqww" @ 111476 -"wz wwwwwwwwwwwwwwww" @ 112234 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 112387 -"wz wwwqwwwqww" @ 112433 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 112697 -"wz wwwqwwwqwwwqwwww" @ 112739 -"wz wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 112770 -"wz wwwwwwwwwwwwwwwwwwwwwwqww" @ 113083 -"wz wwwwwwwwwww" @ 113119 -"wz wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 113136 -"wz wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 113170 -"wz qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 113234 -"wz wqwwwqwwww" @ 113338 -"wz wwqTwwqTww" @ 113414 -"wz DDAQDDDQDDDE" @ 113481 -"wz DDDQDDDEDDDDDDDDTDDD" @ 113494 -"wz DDEQDDQEDDQDDDE" @ 113574 -"wz TDUUDDDDDDDDDADDA" @ 113616 -"wz DDATDDATDD" @ 113673 -"wz DDDTDDEDDDQDDU" @ 113691 -"wz wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 113715 -"wz wwQwwwQwww" @ 113748 -"wz wwwwwwwwwwwwwwwwwwqwwq" @ 113759 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 113793 -"wz wwwwwwvwwwf" @ 115893 -"wz DDDTDDADDD" @ 116021 -"wz DEAQDEATDEATDE" @ 116034 -"wz DDQTDDQDDE" @ 116053 -"wz vfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvf" @ 116162 -"wz ffffffgvfgwffwvfgwvfgwffwwffwvffwvffwvffwvffwvffwvffwvffq" @ 116224 -"wz DDDEDDDDDDDDTDDD" @ 116352 -"wz DDDADDDDDDDDDDDDTDD" @ 116384 -"wz DDEQDDQEDDQDDDE" @ 116428 -"wz DDDDDDADDA" @ 116477 -"wz DDDTDDEDDDQDDU" @ 116545 -"wz wwwwwwwwwwwwwwqwwww" @ 116873 -"wz wwwwwwwwwwww" @ 116896 -"wz wwqwwwwwwwwwwwwwwwwwww" @ 116957 -"wz avafavafawafawqfawqff" @ 117003 -"wz wqwqwqwqwqwqwqwqww" @ 117321 -"wz wwwwwwwwwwwwwww" @ 117600 -"wz wwwwwwwwwww" @ 117622 -"wz wwwwwwwwwwwwwwqwwwqwww" @ 117641 -"wz wwwqwwwwwwwwwwww" @ 117772 -"wz wwwwwwwwwwwwwww" @ 117789 -"wz wwwqwwwqqww" @ 117816 -"wz wwwwwwwwwwww" @ 118910 -"wz wwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 118930 -"wz wwwwwwwwwwqwwq" @ 119239 -"wz wwqwwwqwww" @ 119260 -"wz DEwwwwwwwwwwwwww" @ 119288 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 119311 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|www|" @ 119378 -"wz qwwwqwwwqwwwwwwww" @ 119529 -"wz TDDDTDDDTDDD" @ 119558 -"wz DDEQDDDQDDDE" @ 119587 -"wz DUUTDDDDDDDDDDDD" @ 119626 -"wz DDDTDDDDDDADDDADDD" @ 119651 -"wz DDTDDDDDDDDDDE" @ 119692 -"wz wwwwwwwwwwwwwwww" @ 119834 -"wz 7qTDDqTDDw" @ 119865 -"wz wwwwwwwwDDQ" @ 119890 -"wz DDEQDDDEDDDDDDDDUDDD" @ 119902 -"wz TDDTDDDADDD" @ 119971 -"wz DDDTDDEDUUQDDDEDDDQDDDQDDE" @ 119983 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 120056 -"wz DDDUDDDDTDDDTDDDUUUU" @ 120234 -"wz DDDDDDDDDDDDDDDDDDDDDDDDUDDD" @ 120538 -"wz DDDDDDDDDDDDUUUU" @ 120622 -"wz DDDEDDDEDDDEDDA" @ 120666 -"wz DDEQTDDEUUUU" @ 121002 -"wz DDDDDDDDDDDDDDADDDD" @ 121759 -"wz DDDDDDADDA" @ 121919 -"wz QAဘႈ膈膈膈膈膈膈ႁ" @ 122270 -"wz DDDDDDADDA" @ 122837 -"wz wwwqwwwqwwww" @ 123590 -"wz wwwwwwwqwww" @ 123626 -"wz wwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 123775 -"wz DDDDDDDDDDDDDDADDDD" @ 125895 -"wz DDDDDDADDA" @ 126055 -"wz QAဘႈ膈膈膈膈膈膈ႁ" @ 126406 -"wz DDDDDDADDA" @ 126973 -"wz DDwqDDwqDD" @ 128042 -"wz 333133333333333333333333" @ 129940 -"wz 3333333333333333333333333333333333333333333333333333333333333333" @ 130060 -"wz 333333333333333333333333333333333333333333333313331333333333333333333333333333333313331333" @ 130145 -"wz DDDADDDDDDDADDD" @ 130532 -"wz 3333333333333333333333333333333333333333333333333333333333333333" @ 130652 -"wz 333333333333333333333333333333333333333333333313331333333333333333333333333333333313331333" @ 130737 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 131124 -"wz 3333333333333333333333333333333333333333333333333333333333333333" @ 131244 -"wz 3333333333333333333333333333333333333333DDDADDDADDDDDDDDDDDD" @ 131332 -"wz 33333333333333313331333" @ 131396 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 131716 -"wz 3333333333333333333333333333333333333333333333333333333333333333" @ 131836 -"wz 3331333333333333DDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 131948 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 132308 -"wz 3333333333333333333333333333333333333333333333333333333333333333" @ 132428 -"wz DDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 132553 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 132900 -"wz 3333333333333333333333333331333" @ 133020 -"wz DDDDDDDDDDD" @ 133073 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 133105 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 133492 -"wz 33333333333333333333" @ 133612 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 133636 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 133697 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 134084 -"wz DDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 134220 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 134289 -"wz DDDADDDDDDDDDDDDDDDDDDDD" @ 134676 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 134796 -"wz DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 134881 +wz "SEGA GENESIS (C)SEGA 1995.MARCART. BRADESCO CART. BRADESCO GM 00000001-00W\`J " @ 256 +wz " JUE NqNq\`" @ 432 +wz "N^Nu/\aBGHy" @ 20118 +wz "!&B@N^NuNV" @ 21316 +wz "BEBBBB|\t~\t0\a" @ 23832 +wz "N^Nu/\aBG\fG\n" @ 30962 +wz "AT&FV0B0+FCLASS=1;+FF=1\r" @ 31092 +wz "NMEMORIA CHEIA." @ 31449 +wz "SEM PORTADORA" @ 31465 +wz "INICIANDO TESTE AGUARDE !!!" @ 31479 +wz "LINHA OCUPADA" @ 31507 +wz "NAO ATENDE" @ 31521 +wz "SEM TOM DISCAGEM" @ 31532 +wz "DISCANDO NOVAMENTE" @ 31549 +wz "CONEXAO OK !" @ 31568 +wz "OPER ABORTADA" @ 31581 +wz "ERRO NOVA TENTATIVA" @ 31595 +wz "LINHA DESCONECTADA." @ 31615 +wz "ERRO DE COMUNICACAO" @ 31651 +wz "DADOS INCORRETOS" @ 31671 +wz "ENVIANDO DADOS..." @ 31688 +wz "RECEBENDO DADOS" @ 31706 +wz "FALHA 3 TENTATIVAS" @ 31722 +wz "ERRO NOVA TENTATIVA" @ 31741 +wz "TIMEOUT DADOS" @ 31761 +wz "FINAL RECEPCAO" @ 31775 +wz "ERRO DE CHECKSUM" @ 31795 +wz "TRANSACAO INEXISTE" @ 31812 +wz "DATA,HIST.,DOCTO,VALOR," @ 31831 +wz "SALDO VINCULADO" @ 31860 +wz "SALDO DISPONIVEL,SALDO VINCULADO,SALDO TOTAL," @ 31885 +wz " ERRO CLASS 1 " @ 31949 +wz " " @ 31964 +wz "SALDO ATUAL " @ 31987 +wz "DATA,SALDO TOTAL,DATA,SALDO VINCULADO,DATA,SALDO C/L PROGRAMADO," @ 32003 +wz "FALHA DE COMUNICACAO" @ 32068 +wz "HOST INOPERANTE" @ 32089 +wz "TIMEOUT HOST" @ 32105 +wz "ERRO DE COMUNICACAO" @ 32119 +wz "AGENCIA FORA DO AR" @ 32139 +wz "TRANSMISSAO CANCELADA" @ 32158 +wz "SENHA NAO GRAVADA" @ 32180 +wz "SENHA INVALIDA" @ 32198 +wz "C/C BLOQUEADA" @ 32213 +wz "EXTRATO NAO ENCONTRADO" @ 32227 +wz "SEM LANCAMENTOS" @ 32250 +wz "DIA DE VENCIMENTO INVALIDO" @ 32266 +wz "MES DO EXTRATO INVALIDO" @ 32293 +wz "FIM DE EXTRATO" @ 32317 +wz "AGENCIA INCORRETA" @ 32332 +wz "CADASTRO EM ATUALIZACAO" @ 32350 +wz "CONTA INEXISTENTE" @ 32374 +wz "EXTRATO INEXISTENTE" @ 32392 +wz "CARTAO DE CREDITO" @ 32426 +wz "LANCAMENTOS FUTUROS" @ 32444 +wz "LANCAMENTOS DIA ANTERIOR" @ 32464 +wz " F.A.F. FACIL" @ 32489 +wz "AT+FCLASS=1\r" @ 32504 +wz "AT+FTM=48\r" @ 32547 +wz "AT+FTM=24\r" @ 32558 +wz "AT+FRM=48\r" @ 32569 +wz "AT+FRM=24\r" @ 32580 +wz "DIS FRAME OK" @ 32591 +wz "ERRO RX FRAME" @ 32604 +wz "WAIT DIS FRAME" @ 32650 +wz "ERRO:FRAME DIS" @ 32665 +wz "ERRO FTH=3" @ 32680 +wz " TRAINING..." @ 32700 +wz "RECEPCAO..." @ 32724 +wz "ERRO PROG RX" @ 32827 +wz "RECEBENDO DADOS..." @ 32840 +wz "TRAINING 4800..." @ 32874 +wz "TRAINING 2400..." @ 32891 +wz "TRAINING OK" @ 32908 +wz "ERRO TRAINING" @ 32920 +wz "FALHA:COMUNICACAO" @ 32968 +wz "ERRO BLOCO" @ 33016 +wz "CONTA OU DIGITO INCORRETO" @ 33027 +wz "CODIGO DA AGENCIA INCORRETO" @ 33053 +wz "DATA DO CARTAO DE CREDITO INCORRETA" @ 33081 +wz "001002003005010011004020021022030031999040041042043N" @ 33164 +wz "xqke_ZUPLGC@<952/-*(&#! " @ 37772 +wz "#q#p#s#r#6" @ 38972 +wz " !&+05:?DINSX]bg" @ 39925 +wz "3333333333333333333333333333" @ 42834 +wz "'()*+,-./012" @ 43375 +wz "3456789:;<=>?@" @ 43401 +wz "IJKLMNOPQRST" @ 43455 +wz "ijjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjk" @ 43535 +wz "lmmmmmmmmmmnopq" @ 43615 +wz "qstsssnnmmmmmmmmmmu" @ 43647 +wz "lmmmmmmmmmmvwxyz{|}~" @ 43695 +wz "wmmmmmmmmmu" @ 43743 +wz "lmmmᡭw±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅ" @ 43935 +wz "lmÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåmu" @ 44015 +wz "lmæçèéêëìíîïðñòóôõö÷øùúæû" @ 44095 +wz "'mmmmmmmmu" @ 44385 +wz "'mmmmmmmmu" @ 44465 +wz "lmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmu" @ 44495 +wz "fffffffffa" @ 45590 +wz "faffffffffffa" @ 45687 +wz "ffffffffffff" @ 45806 +wz "fffffffffffaf" @ 45977 +wz "fafffafffafff" @ 46136 +wz "ffffffffffffffffffa" @ 46202 +wz "ffffffffffffffa" @ 46518 +wz "fffafffffa" @ 46574 +wz "fffffffffa" @ 46670 +wz "fffaffffff" @ 46689 +wz "ffafffafffa" @ 46841 +wz "ffafffafafffa" @ 46933 +wz "fafffafffa" @ 47072 +wz "fffffffffa" @ 47169 +wz "faffffffffffa" @ 47247 +wz "fafffafffa" @ 47440 +wz "fffafffffafff" @ 47534 +wz "ffffffffffffffff" @ 47598 +wz "afafffafffa" @ 47726 +wz "ffffffffffffa" @ 48177 +wz "fffffffffffaf" @ 48401 +wz "fafffafafaf" @ 48464 +wz "fafffafffa" @ 48527 +wz ",-./0123456789:;<=543210/.-," @ 57312 +wz ">?@ABCDEFGHIJKLMNOPQQRSTULKJIHGFEDCBA@?>VWX" @ 57343 +wz "XVYZ[\\]^_\`abccbadefgh[ZYVX" @ 57389 +wz "ijDkllmnoopqrstluultsvwxyz{|llkDji" @ 57424 +wz "CDEFGHIJKL*" @ 58042 +wz "MNOPQORSPT*" @ 58062 +wz "Z[\\]^_\`abcdd9*" @ 58121 +wz "efghijklmnopqrstuvwxyz{|}~" @ 58150 +wz "'()*+,-./012" @ 58417 +wz "3456789:;<=>?@" @ 58430 +wz "AB,CDEFGHIJKLMNOPQRST" @ 58445 +wz "QUVWXWYZ[\\]^_R" @ 58467 +wz "\`abcdefghi!j" @ 58482 +wz "opqrstuvwxyz{|\tm" @ 58509 +wz " !\"#$%&'()*+,-./m0" @ 58758 +wz "123456789:;<=46\tm" @ 58786 +wz ">??@?ABCDEFGH@AI\bm" @ 58811 +wz "123456789:8;" @ 59128 +wz "#<=>?@ABC)(D\aEFGHIJKLMNOP" @ 59143 +wz "#QRSTUVWRXYZ" @ 59171 +wz "()*+,-./012" @ 59553 +wz "6789:;<=>?@ABCD" @ 59576 +wz "fghijklmno_^pqrstuvwxyHz" @ 59703 +wz "\"#$%&'()*+,-./0123\"" @ 59953 +wz "PWXYZ[\\]QNF^_\`abO" @ 60055 +wz "PcdefghiQN" @ 60075 +wz " !\"#$%&'\"#\$()*%+," @ 60267 +wz "#$%&'()*+,-./01234$" @ 60665 +wz "&'()*+,-./01" @ 61172 +wz "23456789:;<=" @ 61186 +wz ">?@>ABCDEF@G" @ 61200 +wz "HIJKLJMNOPQR" @ 61214 +wz "STUVWUXYZ[\\]" @ 61228 +wz "'()*+,-./0" @ 61394 +wz "234567891:" @ 61407 +wz "Df33D33JDf" @ 65002 +wz "Df33J433Df" @ 66042 +wz "Df33D3J3Df" @ 66065 +wz "Df334JDJ\b3" @ 66263 +wz "Df33J4J4Df" @ 67100 +wz "Df33D3J3Df33" @ 67124 +wz "Df33JDDJDf33" @ 67300 +wz "3Df33J44JDf" @ 67315 +wz "Df33D34JDd" @ 68078 +wz "Df33J4D4Df" @ 68091 +wz "Df33J43DDf" @ 68133 +wz "Df33J4J3Df" @ 68194 +wz "0\t9\t9\t9\t9\n" @ 89740 +wz "SUSU355355S53553" @ 91822 +wz "5S5S3UU355U53" @ 92487 +wz "U3UU5SS3S3" @ 92515 +wz "wwwwwwwwwwwwwwww" @ 93824 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 93977 +wz "wwwqwwwqww" @ 94023 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 94287 +wz "wwwqwwwqwwwqwwww" @ 94329 +wz "wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 94360 +wz "wwwwwwwwwwwwwwwwwwwwwwqww" @ 94673 +wz "wwwwwwwwwww" @ 94709 +wz "wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 94726 +wz "wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 94760 +wz "qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 94824 +wz "wqwwwqwwww" @ 94928 +wz "wwqTwwqTww" @ 95004 +wz "DDAQDDDQDDDE" @ 95071 +wz "DDDQDDDEDDDDDDDDTDDD" @ 95084 +wz "DDEQDDQEDDQDDDE" @ 95164 +wz "TDUUDDDDDDDDDADDA" @ 95206 +wz "DDATDDATDD" @ 95263 +wz "DDDTDDEDDDQDDU" @ 95281 +wz "wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 95305 +wz "wwQwwwQwww" @ 95338 +wz "wwwwwwwwwwwwwwwwwwqwwq" @ 95349 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 95383 +wz "DDDEDDDDDDDDDDA" @ 95636 +wz "DDUUDDDDDDDDU" @ 95684 +wz "wwwwwwvwwwf" @ 97409 +wz "DDDTDDADDD" @ 97537 +wz "DEAQDEATDEATDE" @ 97550 +wz "DDQTDDQDDE" @ 97569 +wz "vfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvf" @ 97678 +wz "ffffffgvfgwffwvfgwvfgwffwwffwvffwvffwvffwvffwvffwvffwvffq" @ 97740 +wz "DDDEDDDDDDDDTDDD" @ 97868 +wz "DDDADDDDDDDDDDDDTDD" @ 97900 +wz "DDEQDDQEDDQDDDE" @ 97944 +wz "DDDDDDADDA" @ 97993 +wz "DDDTDDEDDDQDDU" @ 98061 +wz "wwwwwwwwwwwwwwqwwww" @ 98389 +wz "wwwwwwwwwwww" @ 98412 +wz "wwqwwwwwwwwwwwwwwwwwww" @ 98473 +wz "avafavafawafawqfawqff" @ 98519 +wz "wwqqwwqqwww" @ 98835 +wz "wwwqwwwqww" @ 98994 +wz "wwwwwwwwwwwwww" @ 99041 +wz "wwwwwwwwwwwwwwww" @ 99906 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 100059 +wz "wwwqwwwqww" @ 100105 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 100369 +wz "wwwqwwwqwwwqwwww" @ 100411 +wz "wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 100442 +wz "wwwwwwwwwwwwwwwwwwwwwwqww" @ 100755 +wz "wwwwwwwwwww" @ 100791 +wz "wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 100808 +wz "wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 100842 +wz "qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 100906 +wz "wqwwwqwwww" @ 101010 +wz "wwqTwwqTww" @ 101086 +wz "DDAQDDDQDDDE" @ 101153 +wz "DDDQDDDEDDDDDDDDTDDD" @ 101166 +wz "DDEQDDQEDDQDDDE" @ 101246 +wz "TDUUDDDDDDDDDADDA" @ 101288 +wz "DDATDDATDD" @ 101345 +wz "DDDTDDEDDDQDDU" @ 101363 +wz "wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 101387 +wz "wwQwwwQwww" @ 101420 +wz "wwwwwwwwwwwwwwwwwwqwwq" @ 101431 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 101465 +wz "DDDEDDDDDDDDDDA" @ 101718 +wz "DDUUDDDDDDDDU" @ 101766 +wz "wwwwwwvwwwf" @ 103487 +wz "DDDTDDADDD" @ 103615 +wz "DEAQDEATDEATDE" @ 103628 +wz "DDQTDDQDDE" @ 103647 +wz "vffwvffwvffwvffwvfgwvfgwvfwwvfwfffffgvfgwffwvffwvffwfffwfffvffafaTDf" @ 103723 +wz "DDDUDDDDDDDDTDDD" @ 103822 +wz "wvffwvffwvffwvffwvffwvffq" @ 104138 +wz "DDDADDDDDDDDDDDDTDD" @ 104202 +wz "wwwwwwwwwwwwwwqwwww" @ 104499 +wz "wwwwwwwwwwww" @ 104522 +wz "wwqwwwwwwwwwwwwwwwwwww" @ 104583 +wz "avafavafawafawqfawqff" @ 104629 +wz "wwqqwwqqwww" @ 104945 +wz "wwwqwwwqww" @ 105104 +wz "wwwwwwwwwwwwww" @ 105151 +wz "wwwwwwwwwwwwwwww" @ 106026 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 106179 +wz "wwwqwwwqww" @ 106225 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 106489 +wz "wwwqwwwqwwwqwwww" @ 106531 +wz "wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 106562 +wz "wwwwwwwwwwwwwwwwwwwwwwqww" @ 106875 +wz "wwwwwwwwwww" @ 106911 +wz "wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 106928 +wz "wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 106962 +wz "qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 107026 +wz "wqwwwqwwww" @ 107130 +wz "wwqTwwqTww" @ 107206 +wz "DDAQDDDQDDDE" @ 107273 +wz "DDDQDDDEDDDDDDDDTDDD" @ 107286 +wz "DDEQDDQEDDQDDDE" @ 107366 +wz "TDUUDDDDDDDDDADDA" @ 107408 +wz "DDATDDATDD" @ 107465 +wz "DDDTDDEDDDQDDU" @ 107483 +wz "wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 107507 +wz "wwQwwwQwww" @ 107540 +wz "wwwwwwwwwwwwwwwwwwqwwq" @ 107551 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 107585 +wz "DDDEDDDDDDDDDDA" @ 107838 +wz "DDUUDDDDDDDDU" @ 107886 +wz "wwwwwwvwwwf" @ 109649 +wz "DDDTDDADDD" @ 109777 +wz "DEAQDEATDEATDE" @ 109790 +wz "DDQTDDQDDE" @ 109809 +wz "vffwvffwvffwvffwvfgwvfgwvfwwvfwfffffgvfgwffwvffwvffwfffwfffvffafaTDf" @ 109885 +wz "DDDUDDDDDDDDTDDD" @ 109984 +wz "wvffwvffwvffwvffwvffwvffq" @ 110300 +wz "DDDADDDDDDDDDDDDTDD" @ 110364 +wz "wwwwwwwwwwwwwwqwwww" @ 110661 +wz "wwwwwwwwwwww" @ 110684 +wz "wwqwwwwwwwwwwwwwwwwwww" @ 110745 +wz "avafavafawafawqfawqff" @ 110791 +wz "qwqwqwqwqww" @ 111116 +wz "wwwwwwwwwwwwwww" @ 111260 +wz "wwwwwwwwwww" @ 111282 +wz "wwwwwwwwwwwwwwqwwwqwww" @ 111301 +wz "wwwqwwwwwwwwwwww" @ 111432 +wz "wwwwwwwwwwwwwww" @ 111449 +wz "wwwqwwwqqww" @ 111476 +wz "wwwwwwwwwwwwwwww" @ 112234 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwww" @ 112387 +wz "wwwqwwwqww" @ 112433 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 112697 +wz "wwwqwwwqwwwqwwww" @ 112739 +wz "wwwqwwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 112770 +wz "wwwwwwwwwwwwwwwwwwwwwwqww" @ 113083 +wz "wwwwwwwwwww" @ 113119 +wz "wwDQwwDQwwwwwqwwwqwwwwwwwwwwww" @ 113136 +wz "wwwwwwwwwwwwwwwwwwwwwwwqwwwqwwwqwww" @ 113170 +wz "qqဗ焗焗􇝷􇝷􇝷􇝷􇝷" @ 113234 +wz "wqwwwqwwww" @ 113338 +wz "wwqTwwqTww" @ 113414 +wz "DDAQDDDQDDDE" @ 113481 +wz "DDDQDDDEDDDDDDDDTDDD" @ 113494 +wz "DDEQDDQEDDQDDDE" @ 113574 +wz "TDUUDDDDDDDDDADDA" @ 113616 +wz "DDATDDATDD" @ 113673 +wz "DDDTDDEDDDQDDU" @ 113691 +wz "wwwwwwwDQwwDQwwDQwwDQwwDQwwE" @ 113715 +wz "wwQwwwQwww" @ 113748 +wz "wwwwwwwwwwwwwwwwwwqwwq" @ 113759 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 113793 +wz "wwwwwwvwwwf" @ 115893 +wz "DDDTDDADDD" @ 116021 +wz "DEAQDEATDEATDE" @ 116034 +wz "DDQTDDQDDE" @ 116053 +wz "vfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvfwwvf" @ 116162 +wz "ffffffgvfgwffwvfgwvfgwffwwffwvffwvffwvffwvffwvffwvffwvffq" @ 116224 +wz "DDDEDDDDDDDDTDDD" @ 116352 +wz "DDDADDDDDDDDDDDDTDD" @ 116384 +wz "DDEQDDQEDDQDDDE" @ 116428 +wz "DDDDDDADDA" @ 116477 +wz "DDDTDDEDDDQDDU" @ 116545 +wz "wwwwwwwwwwwwwwqwwww" @ 116873 +wz "wwwwwwwwwwww" @ 116896 +wz "wwqwwwwwwwwwwwwwwwwwww" @ 116957 +wz "avafavafawafawqfawqff" @ 117003 +wz "wqwqwqwqwqwqwqwqww" @ 117321 +wz "wwwwwwwwwwwwwww" @ 117600 +wz "wwwwwwwwwww" @ 117622 +wz "wwwwwwwwwwwwwwqwwwqwww" @ 117641 +wz "wwwqwwwwwwwwwwww" @ 117772 +wz "wwwwwwwwwwwwwww" @ 117789 +wz "wwwqwwwqqww" @ 117816 +wz "wwwwwwwwwwww" @ 118910 +wz "wwwqwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 118930 +wz "wwwwwwwwwwqwwq" @ 119239 +wz "wwqwwwqwww" @ 119260 +wz "DEwwwwwwwwwwwwww" @ 119288 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 119311 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww|www|" @ 119378 +wz "qwwwqwwwqwwwwwwww" @ 119529 +wz "TDDDTDDDTDDD" @ 119558 +wz "DDEQDDDQDDDE" @ 119587 +wz "DUUTDDDDDDDDDDDD" @ 119626 +wz "DDDTDDDDDDADDDADDD" @ 119651 +wz "DDTDDDDDDDDDDE" @ 119692 +wz "wwwwwwwwwwwwwwww" @ 119834 +wz "7qTDDqTDDw" @ 119865 +wz "wwwwwwwwDDQ" @ 119890 +wz "DDEQDDDEDDDDDDDDUDDD" @ 119902 +wz "TDDTDDDADDD" @ 119971 +wz "DDDTDDEDUUQDDDEDDDQDDDQDDE" @ 119983 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwqwwq" @ 120056 +wz "DDDUDDDDTDDDTDDDUUUU" @ 120234 +wz "DDDDDDDDDDDDDDDDDDDDDDDDUDDD" @ 120538 +wz "DDDDDDDDDDDDUUUU" @ 120622 +wz "DDDEDDDEDDDEDDA" @ 120666 +wz "DDEQTDDEUUUU" @ 121002 +wz "DDDDDDDDDDDDDDADDDD" @ 121759 +wz "DDDDDDADDA" @ 121919 +wz "QAဘႈ膈膈膈膈膈膈ႁ" @ 122270 +wz "DDDDDDADDA" @ 122837 +wz "wwwqwwwqwwww" @ 123590 +wz "wwwwwwwqwww" @ 123626 +wz "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwww" @ 123775 +wz "DDDDDDDDDDDDDDADDDD" @ 125895 +wz "DDDDDDADDA" @ 126055 +wz "QAဘႈ膈膈膈膈膈膈ႁ" @ 126406 +wz "DDDDDDADDA" @ 126973 +wz "DDwqDDwqDD" @ 128042 +wz "333133333333333333333333" @ 129940 +wz "3333333333333333333333333333333333333333333333333333333333333333" @ 130060 +wz "333333333333333333333333333333333333333333333313331333333333333333333333333333333313331333" @ 130145 +wz "DDDADDDDDDDADDD" @ 130532 +wz "3333333333333333333333333333333333333333333333333333333333333333" @ 130652 +wz "333333333333333333333333333333333333333333333313331333333333333333333333333333333313331333" @ 130737 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 131124 +wz "3333333333333333333333333333333333333333333333333333333333333333" @ 131244 +wz "3333333333333333333333333333333333333333DDDADDDADDDDDDDDDDDD" @ 131332 +wz "33333333333333313331333" @ 131396 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 131716 +wz "3333333333333333333333333333333333333333333333333333333333333333" @ 131836 +wz "3331333333333333DDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 131948 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 132308 +wz "3333333333333333333333333333333333333333333333333333333333333333" @ 132428 +wz "DDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 132553 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 132900 +wz "3333333333333333333333333331333" @ 133020 +wz "DDDDDDDDDDD" @ 133073 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 133105 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 133492 +wz "33333333333333333333" @ 133612 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 133636 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 133697 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 134084 +wz "DDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 134220 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 134289 +wz "DDDADDDDDDDDDDDDDDDDDDDD" @ 134676 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" @ 134796 +wz "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDADDDADDD" @ 134881 diff --git a/test/unit/test_debruijn.c b/test/unit/test_debruijn.c index 67f62ff4cb..ba83fbbeae 100644 --- a/test/unit/test_debruijn.c +++ b/test/unit/test_debruijn.c @@ -7,17 +7,24 @@ bool test_rz_debruijn_pattern(void) { char *pattern = rz_debruijn_pattern(256, 0, NULL /*default charset*/); mu_assert_eq((int)strlen(pattern), 256, "pattern length"); - mu_assert_streq(pattern, "AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAhAAiAAjAAkAAlAAmAAnAAoAApAAqAArAAsAAtAAuAAvAAwAAxAAyAAzAA1AA2AA3AA4AA5AA6AA7AA8AA9AA0ABBABCABDABEABFABGABHABIABJABKABLABMABNABOABPABQABRABSABTABUABVABWABXABY", "pattern of 256 length"); - free(pattern); + mu_assert_streq_free(pattern, "AAABAACAADAAEAAFAAGAAHAAIAAJAAKAALAAMAANAAOAAPAAQAARAASAATAAUAAVAAWAAXAAYAAZAAaAAbAAcAAdAAeAAfAAgAAhAAiAAjAAkAAlAAmAAnAAoAApAAqAArAAsAAtAAuAAvAAwAAxAAyAAzAA1AA2AA3AA4AA5AA6AA7AA8AA9AA0ABBABCABDABEABFABGABHABIABJABKABLABMABNABOABPABQABRABSABTABUABVABWABXABY", "pattern of 256 length"); + pattern = rz_debruijn_pattern(10, 2, "12345"); + mu_assert_eq((int)strlen(pattern), 10, "pattern length"); + eprintf("pattern = '%s'\n", pattern); + mu_assert_streq_free(pattern, "1211311411", "pattern of length 10"); mu_end; } bool test_rz_debruijn_offset(void) { // From ropasaurusrex. ut64 offset = 0x41417641; - mu_assert_eq(rz_debruijn_offset(offset, false /*little endian*/), 140, "debruijn offset - little endian"); + mu_assert_eq(rz_debruijn_offset(0, NULL, offset, false), 140, "debruijn offset - little endian"); offset = 0x41764141; - mu_assert_eq(rz_debruijn_offset(offset, true /*big endian*/), 140, "debruijn offset - big endian"); + mu_assert_eq(rz_debruijn_offset(0, NULL, offset, true), 140, "debruijn offset - big endian"); + offset = 0x31313331; + mu_assert_eq(rz_debruijn_offset(2, "12345", offset, true), 2, "debruijn offset - big endian"); + offset = 0x31313331; + mu_assert_eq(rz_debruijn_offset(2, "12345", offset, false), 3, "debruijn offset - little endian"); mu_end; } @@ -27,4 +34,4 @@ int all_tests() { return tests_passed != tests_run; } -mu_main(all_tests) \ No newline at end of file +mu_main(all_tests) diff --git a/test/unit/test_util.c b/test/unit/test_util.c index 5e0f9afcaa..fb94cc4560 100644 --- a/test/unit/test_util.c +++ b/test/unit/test_util.c @@ -40,8 +40,29 @@ bool test_file_slurp(void) { mu_end; } +bool test_endian(void) { + ut8 buf[8]; + rz_write_be16(buf, 0x1122); + mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "be16"); + rz_write_le16(buf, 0x1122); + mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "le16"); + + rz_write_be32(buf, 0x11223344); + mu_assert_memeq((ut8 *)"\x11\x22\x33\x44", buf, 4, "be32"); + rz_write_le32(buf, 0x11223344); + mu_assert_memeq((ut8 *)"\x44\x33\x22\x11", buf, 4, "le32"); + + rz_write_ble(buf, 0x1122, true, 16); + mu_assert_memeq((ut8 *)"\x11\x22", buf, 2, "ble 16 true"); + rz_write_ble(buf, 0x1122, false, 16); + mu_assert_memeq((ut8 *)"\x22\x11", buf, 2, "ble 16 false"); + + mu_end; +} + int all_tests() { mu_run_test(test_file_slurp); + mu_run_test(test_endian); return tests_passed != tests_run; }