Port c commands to newshell (#1854)

Co-authored-by: Riccardo Schirone <ret2libc@users.noreply.github.com>
This commit is contained in:
Dhruv Maroo 2021-11-25 17:55:08 +05:30 committed by GitHub
parent 516c02f0e5
commit 0801f7adf6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 2846 additions and 810 deletions

View file

@ -2126,6 +2126,7 @@ static bool cb_scrcolumns(void *user, void *data) {
int n = atoi(node->value);
core->cons->force_columns = n;
core->dbg->regcols = n / 20;
rz_cons_get_size(NULL);
return true;
}

View file

@ -6022,7 +6022,6 @@ RZ_API void rz_core_cmd_init(RzCore *core) {
{ "<", "pipe into RzCons.readChar", rz_cmd_pipein },
{ "0", "alias for s 0x", rz_cmd_ox },
{ "a", "analysis", rz_cmd_analysis },
{ "c", "compare memory", rz_cmd_cmp },
{ "d", "debugger operations", rz_cmd_debug },
{ "f", "get/set flags", rz_cmd_flag },
{ "k", "perform sdb query", rz_cmd_kuery },

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,169 @@
# SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
# SPDX-License-Identifier: LGPL-3.0-only
---
name: cmd_cmp
commands:
- name: c
summary: Compare an escaped <string> with data at current offset
cname: cmd_cmp_string
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: string
type: RZ_CMD_ARG_TYPE_STRING
- name: c1
summary: Compare 8-bit data at current offset with the data at <addr>
cname: cmd_cmp_bits
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM
- name: ca
summary: Compare <n> bytes of data at <addr> with the data at current offset
cname: cmd_cmp_addr
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM
- name: n
type: RZ_CMD_ARG_TYPE_NUM
- name: cb
summary: Compare <n> (up to 8) bytes at current offset with a number <num>
cname: cmd_cmp_bytes
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: num
type: RZ_CMD_ARG_TYPE_RZNUM
- name: n
type: RZ_CMD_ARG_TYPE_NUM
- name: cc
summary: Compare hexdump of data of block size at <addr> with the data at current offset
cname: cmd_cmp_hex_block
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM
- name: ccc
summary: Show different lines between hexdump of a block of data at <addr> wth the data at current offset
cname: cmd_cmp_hex_diff_lines
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM
- name: ccd
summary: Compare disassembly of block size at <addr> and at the current offset
cname: cmd_cmp_disasm
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM
optional: true
- name: cf
summary: Compare the contents of <file> with the data at current offset
cname: cmd_cmp_file
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: file
type: RZ_CMD_ARG_TYPE_FILE
- name: cu
summary: Unified diff commands
subcommands:
- name: cu
summary: Compare data at <offset> with the current offset
cname: cmd_cmp_unified
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
details:
- name: Applying patches
entries:
- text: "Apply unified hex patch"
comment: "cu <offset> > file; wu file"
- name: cu1
summary: Compare bytes at <offset> with the current offset
cname: cmd_cmp_unified1
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
- name: cu2
summary: Compare words (16-bit) at <offset> with the current offset
cname: cmd_cmp_unified2
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
- name: cu4
summary: Compare dwords (32-bit) at <offset> with the current offset
cname: cmd_cmp_unified4
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
- name: cu8
summary: Compare qwords (64-bit) at <offset> with the current offset
cname: cmd_cmp_unified8
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
- name: cud
summary: Compare disassembly at <offset> with the current offset
cname: cmd_cmp_unified_disasm
args:
- name: offset
type: RZ_CMD_ARG_TYPE_RZNUM
- name: cw
summary: Compare watcher commands
subcommands:
- name: cw
summary: Add a memory watcher of size <sz> and command <cmd> at current offset
cname: cmd_cmp_add_memory_watcher
args:
- name: sz
type: RZ_CMD_ARG_TYPE_NUM
- name: cmd
type: RZ_CMD_ARG_TYPE_CMD
- name: cwl
summary: List all compare watchers
cname: cmd_cmp_list_compare_watchers
type: RZ_CMD_DESC_TYPE_ARGV_MODES
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_RIZIN
args: []
- name: cwr
summary: Reset/revert watcher at current offset
cname: cmd_cmp_reset_watcher
args: []
- name: cwu
summary: Update watcher at current offset
cname: cmd_cmp_update_watcher
args: []
- name: cwx
summary: Remove watcher at current offset
cname: cmd_cmp_remove_watcher
args: []
- name: cx
summary: Compare data at current offset with a hexpair string <hexpair> (also return in $?)
cname: cmd_cmp_hexpair_string
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: hexpair
type: RZ_CMD_ARG_TYPE_STRING
- name: cX
summary: Compare hexdump of data of block size at <addr> with the data at current offset using hexdiff output
cname: cmd_cmp_hex_block_hexdiff
type: RZ_CMD_DESC_TYPE_ARGV_STATE
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
args:
- name: addr
type: RZ_CMD_ARG_TYPE_RZNUM

View file

@ -11,6 +11,7 @@ static const RzCmdDescDetail system_details[2];
static const RzCmdDescDetail system_to_cons_details[2];
static const RzCmdDescDetail hash_bang_details[2];
static const RzCmdDescDetail pointer_details[2];
static const RzCmdDescDetail cmd_cmp_unified_details[2];
static const RzCmdDescDetail cmd_debug_list_bp_details[2];
static const RzCmdDescDetail cmd_debug_add_cond_bp_details[2];
static const RzCmdDescDetail cmd_debug_add_watchpoint_details[2];
@ -113,6 +114,23 @@ static const RzCmdDescArg block_increase_args[2];
static const RzCmdDescArg block_flag_args[2];
static const RzCmdDescArg block_max_args[2];
static const RzCmdDescArg basefind_compute_args[2];
static const RzCmdDescArg cmd_cmp_string_args[2];
static const RzCmdDescArg cmd_cmp_bits_args[2];
static const RzCmdDescArg cmd_cmp_addr_args[3];
static const RzCmdDescArg cmd_cmp_bytes_args[3];
static const RzCmdDescArg cmd_cmp_hex_block_args[2];
static const RzCmdDescArg cmd_cmp_hex_diff_lines_args[2];
static const RzCmdDescArg cmd_cmp_disasm_args[2];
static const RzCmdDescArg cmd_cmp_file_args[2];
static const RzCmdDescArg cmd_cmp_unified_args[2];
static const RzCmdDescArg cmd_cmp_unified1_args[2];
static const RzCmdDescArg cmd_cmp_unified2_args[2];
static const RzCmdDescArg cmd_cmp_unified4_args[2];
static const RzCmdDescArg cmd_cmp_unified8_args[2];
static const RzCmdDescArg cmd_cmp_unified_disasm_args[2];
static const RzCmdDescArg cmd_cmp_add_memory_watcher_args[3];
static const RzCmdDescArg cmd_cmp_hexpair_string_args[2];
static const RzCmdDescArg cmd_cmp_hex_block_hexdiff_args[2];
static const RzCmdDescArg comment_args[2];
static const RzCmdDescArg comment_append_args[2];
static const RzCmdDescArg comment_filelink_args[2];
@ -2004,9 +2022,306 @@ static const RzCmdDescHelp basefind_compute_help = {
.args = basefind_compute_args,
};
static const RzCmdDescHelp cmd_cmp_help = {
static const RzCmdDescHelp c_help = {
.summary = "Compare block with given data",
};
static const RzCmdDescArg cmd_cmp_string_args[] = {
{
.name = "string",
.type = RZ_CMD_ARG_TYPE_STRING,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_string_help = {
.summary = "Compare an escaped <string> with data at current offset",
.args = cmd_cmp_string_args,
};
static const RzCmdDescArg cmd_cmp_bits_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_bits_help = {
.summary = "Compare 8-bit data at current offset with the data at <addr>",
.args = cmd_cmp_bits_args,
};
static const RzCmdDescArg cmd_cmp_addr_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
},
{
.name = "n",
.type = RZ_CMD_ARG_TYPE_NUM,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_addr_help = {
.summary = "Compare <n> bytes of data at <addr> with the data at current offset",
.args = cmd_cmp_addr_args,
};
static const RzCmdDescArg cmd_cmp_bytes_args[] = {
{
.name = "num",
.type = RZ_CMD_ARG_TYPE_RZNUM,
},
{
.name = "n",
.type = RZ_CMD_ARG_TYPE_NUM,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_bytes_help = {
.summary = "Compare <n> (up to 8) bytes at current offset with a number <num>",
.args = cmd_cmp_bytes_args,
};
static const RzCmdDescArg cmd_cmp_hex_block_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_hex_block_help = {
.summary = "Compare hexdump of data of block size at <addr> with the data at current offset",
.args = cmd_cmp_hex_block_args,
};
static const RzCmdDescArg cmd_cmp_hex_diff_lines_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_hex_diff_lines_help = {
.summary = "Show different lines between hexdump of a block of data at <addr> wth the data at current offset",
.args = cmd_cmp_hex_diff_lines_args,
};
static const RzCmdDescArg cmd_cmp_disasm_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
.optional = true,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_disasm_help = {
.summary = "Compare disassembly of block size at <addr> and at the current offset",
.args = cmd_cmp_disasm_args,
};
static const RzCmdDescArg cmd_cmp_file_args[] = {
{
.name = "file",
.type = RZ_CMD_ARG_TYPE_FILE,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_file_help = {
.summary = "Compare the contents of <file> with the data at current offset",
.args = cmd_cmp_file_args,
};
static const RzCmdDescHelp cu_help = {
.summary = "Unified diff commands",
};
static const RzCmdDescDetailEntry cmd_cmp_unified_Applying_space_patches_detail_entries[] = {
{ .text = "Apply unified hex patch", .arg_str = NULL, .comment = "cu <offset> > file; wu file" },
{ 0 },
};
static const RzCmdDescDetail cmd_cmp_unified_details[] = {
{ .name = "Applying patches", .entries = cmd_cmp_unified_Applying_space_patches_detail_entries },
{ 0 },
};
static const RzCmdDescArg cmd_cmp_unified_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified_help = {
.summary = "Compare data at <offset> with the current offset",
.details = cmd_cmp_unified_details,
.args = cmd_cmp_unified_args,
};
static const RzCmdDescArg cmd_cmp_unified1_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified1_help = {
.summary = "Compare bytes at <offset> with the current offset",
.args = cmd_cmp_unified1_args,
};
static const RzCmdDescArg cmd_cmp_unified2_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified2_help = {
.summary = "Compare words (16-bit) at <offset> with the current offset",
.args = cmd_cmp_unified2_args,
};
static const RzCmdDescArg cmd_cmp_unified4_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified4_help = {
.summary = "Compare dwords (32-bit) at <offset> with the current offset",
.args = cmd_cmp_unified4_args,
};
static const RzCmdDescArg cmd_cmp_unified8_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified8_help = {
.summary = "Compare qwords (64-bit) at <offset> with the current offset",
.args = cmd_cmp_unified8_args,
};
static const RzCmdDescArg cmd_cmp_unified_disasm_args[] = {
{
.name = "offset",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_unified_disasm_help = {
.summary = "Compare disassembly at <offset> with the current offset",
.args = cmd_cmp_unified_disasm_args,
};
static const RzCmdDescHelp cw_help = {
.summary = "Compare watcher commands",
};
static const RzCmdDescArg cmd_cmp_add_memory_watcher_args[] = {
{
.name = "sz",
.type = RZ_CMD_ARG_TYPE_NUM,
},
{
.name = "cmd",
.type = RZ_CMD_ARG_TYPE_CMD,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_add_memory_watcher_help = {
.summary = "Add a memory watcher of size <sz> and command <cmd> at current offset",
.args = cmd_cmp_add_memory_watcher_args,
};
static const RzCmdDescArg cmd_cmp_list_compare_watchers_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_list_compare_watchers_help = {
.summary = "List all compare watchers",
.args = cmd_cmp_list_compare_watchers_args,
};
static const RzCmdDescArg cmd_cmp_reset_watcher_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_reset_watcher_help = {
.summary = "Reset/revert watcher at current offset",
.args = cmd_cmp_reset_watcher_args,
};
static const RzCmdDescArg cmd_cmp_update_watcher_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_update_watcher_help = {
.summary = "Update watcher at current offset",
.args = cmd_cmp_update_watcher_args,
};
static const RzCmdDescArg cmd_cmp_remove_watcher_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_remove_watcher_help = {
.summary = "Remove watcher at current offset",
.args = cmd_cmp_remove_watcher_args,
};
static const RzCmdDescArg cmd_cmp_hexpair_string_args[] = {
{
.name = "hexpair",
.type = RZ_CMD_ARG_TYPE_STRING,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_hexpair_string_help = {
.summary = "Compare data at current offset with a hexpair string <hexpair> (also return in $?)",
.args = cmd_cmp_hexpair_string_args,
};
static const RzCmdDescArg cmd_cmp_hex_block_hexdiff_args[] = {
{
.name = "addr",
.type = RZ_CMD_ARG_TYPE_RZNUM,
.flags = RZ_CMD_ARG_FLAG_LAST,
},
{ 0 },
};
static const RzCmdDescHelp cmd_cmp_hex_block_hexdiff_help = {
.summary = "Compare hexdump of data of block size at <addr> with the data at current offset using hexdiff output",
.args = cmd_cmp_hex_block_hexdiff_args,
};
static const RzCmdDescHelp C_help = {
.summary = "Code metadata (comments, format, hints, ..)",
@ -8286,8 +8601,65 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
rz_warn_if_fail(basefind_compute_cd);
rz_cmd_desc_set_default_mode(basefind_compute_cd, RZ_OUTPUT_MODE_TABLE);
RzCmdDesc *cmd_cmp_cd = rz_cmd_desc_oldinput_new(core->rcmd, root_cd, "c", rz_cmd_cmp, &cmd_cmp_help);
rz_warn_if_fail(cmd_cmp_cd);
RzCmdDesc *c_cd = rz_cmd_desc_group_state_new(core->rcmd, root_cd, "c", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_string_handler, &cmd_cmp_string_help, &c_help);
rz_warn_if_fail(c_cd);
RzCmdDesc *cmd_cmp_bits_cd = rz_cmd_desc_argv_new(core->rcmd, c_cd, "c1", rz_cmd_cmp_bits_handler, &cmd_cmp_bits_help);
rz_warn_if_fail(cmd_cmp_bits_cd);
RzCmdDesc *cmd_cmp_addr_cd = rz_cmd_desc_argv_state_new(core->rcmd, c_cd, "ca", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_addr_handler, &cmd_cmp_addr_help);
rz_warn_if_fail(cmd_cmp_addr_cd);
RzCmdDesc *cmd_cmp_bytes_cd = rz_cmd_desc_argv_state_new(core->rcmd, c_cd, "cb", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_bytes_handler, &cmd_cmp_bytes_help);
rz_warn_if_fail(cmd_cmp_bytes_cd);
RzCmdDesc *cmd_cmp_hex_block_cd = rz_cmd_desc_argv_new(core->rcmd, c_cd, "cc", rz_cmd_cmp_hex_block_handler, &cmd_cmp_hex_block_help);
rz_warn_if_fail(cmd_cmp_hex_block_cd);
RzCmdDesc *cmd_cmp_hex_diff_lines_cd = rz_cmd_desc_argv_new(core->rcmd, c_cd, "ccc", rz_cmd_cmp_hex_diff_lines_handler, &cmd_cmp_hex_diff_lines_help);
rz_warn_if_fail(cmd_cmp_hex_diff_lines_cd);
RzCmdDesc *cmd_cmp_disasm_cd = rz_cmd_desc_argv_new(core->rcmd, c_cd, "ccd", rz_cmd_cmp_disasm_handler, &cmd_cmp_disasm_help);
rz_warn_if_fail(cmd_cmp_disasm_cd);
RzCmdDesc *cmd_cmp_file_cd = rz_cmd_desc_argv_state_new(core->rcmd, c_cd, "cf", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_file_handler, &cmd_cmp_file_help);
rz_warn_if_fail(cmd_cmp_file_cd);
RzCmdDesc *cu_cd = rz_cmd_desc_group_new(core->rcmd, c_cd, "cu", rz_cmd_cmp_unified_handler, &cmd_cmp_unified_help, &cu_help);
rz_warn_if_fail(cu_cd);
RzCmdDesc *cmd_cmp_unified1_cd = rz_cmd_desc_argv_new(core->rcmd, cu_cd, "cu1", rz_cmd_cmp_unified1_handler, &cmd_cmp_unified1_help);
rz_warn_if_fail(cmd_cmp_unified1_cd);
RzCmdDesc *cmd_cmp_unified2_cd = rz_cmd_desc_argv_new(core->rcmd, cu_cd, "cu2", rz_cmd_cmp_unified2_handler, &cmd_cmp_unified2_help);
rz_warn_if_fail(cmd_cmp_unified2_cd);
RzCmdDesc *cmd_cmp_unified4_cd = rz_cmd_desc_argv_new(core->rcmd, cu_cd, "cu4", rz_cmd_cmp_unified4_handler, &cmd_cmp_unified4_help);
rz_warn_if_fail(cmd_cmp_unified4_cd);
RzCmdDesc *cmd_cmp_unified8_cd = rz_cmd_desc_argv_new(core->rcmd, cu_cd, "cu8", rz_cmd_cmp_unified8_handler, &cmd_cmp_unified8_help);
rz_warn_if_fail(cmd_cmp_unified8_cd);
RzCmdDesc *cmd_cmp_unified_disasm_cd = rz_cmd_desc_argv_new(core->rcmd, cu_cd, "cud", rz_cmd_cmp_unified_disasm_handler, &cmd_cmp_unified_disasm_help);
rz_warn_if_fail(cmd_cmp_unified_disasm_cd);
RzCmdDesc *cw_cd = rz_cmd_desc_group_new(core->rcmd, c_cd, "cw", rz_cmd_cmp_add_memory_watcher_handler, &cmd_cmp_add_memory_watcher_help, &cw_help);
rz_warn_if_fail(cw_cd);
RzCmdDesc *cmd_cmp_list_compare_watchers_cd = rz_cmd_desc_argv_modes_new(core->rcmd, cw_cd, "cwl", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN, rz_cmd_cmp_list_compare_watchers_handler, &cmd_cmp_list_compare_watchers_help);
rz_warn_if_fail(cmd_cmp_list_compare_watchers_cd);
RzCmdDesc *cmd_cmp_reset_watcher_cd = rz_cmd_desc_argv_new(core->rcmd, cw_cd, "cwr", rz_cmd_cmp_reset_watcher_handler, &cmd_cmp_reset_watcher_help);
rz_warn_if_fail(cmd_cmp_reset_watcher_cd);
RzCmdDesc *cmd_cmp_update_watcher_cd = rz_cmd_desc_argv_new(core->rcmd, cw_cd, "cwu", rz_cmd_cmp_update_watcher_handler, &cmd_cmp_update_watcher_help);
rz_warn_if_fail(cmd_cmp_update_watcher_cd);
RzCmdDesc *cmd_cmp_remove_watcher_cd = rz_cmd_desc_argv_new(core->rcmd, cw_cd, "cwx", rz_cmd_cmp_remove_watcher_handler, &cmd_cmp_remove_watcher_help);
rz_warn_if_fail(cmd_cmp_remove_watcher_cd);
RzCmdDesc *cmd_cmp_hexpair_string_cd = rz_cmd_desc_argv_state_new(core->rcmd, c_cd, "cx", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_hexpair_string_handler, &cmd_cmp_hexpair_string_help);
rz_warn_if_fail(cmd_cmp_hexpair_string_cd);
RzCmdDesc *cmd_cmp_hex_block_hexdiff_cd = rz_cmd_desc_argv_state_new(core->rcmd, c_cd, "cX", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_cmp_hex_block_hexdiff_handler, &cmd_cmp_hex_block_hexdiff_help);
rz_warn_if_fail(cmd_cmp_hex_block_hexdiff_cd);
RzCmdDesc *C_cd = rz_cmd_desc_group_state_new(core->rcmd, root_cd, "C", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_LONG, rz_meta_list_handler, &meta_list_help, &C_help);
rz_warn_if_fail(C_cd);

View file

@ -125,7 +125,27 @@ RZ_IPI RzCmdStatus rz_block_increase_handler(RzCore *core, int argc, const char
RZ_IPI RzCmdStatus rz_block_flag_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_block_max_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_basefind_compute_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI int rz_cmd_cmp(void *data, const char *input);
RZ_IPI RzCmdStatus rz_cmd_cmp_string_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_cmd_cmp_bits_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_addr_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_cmd_cmp_bytes_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_cmd_cmp_hex_block_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_hex_diff_lines_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_disasm_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_file_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified1_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified2_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified4_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified8_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_unified_disasm_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_add_memory_watcher_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_list_compare_watchers_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
RZ_IPI RzCmdStatus rz_cmd_cmp_reset_watcher_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_update_watcher_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_remove_watcher_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_cmp_hexpair_string_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_cmd_cmp_hex_block_hexdiff_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_meta_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_meta_list_at_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
RZ_IPI RzCmdStatus rz_meta_remove_handler(RzCore *core, int argc, const char **argv);

View file

@ -199,9 +199,8 @@ commands:
optional: true
choices: ["32", "64"]
- name: c
cname: cmd_cmp
summary: Compare block with given data
type: RZ_CMD_DESC_TYPE_OLDINPUT
subcommands: cmd_cmp
- name: C
summary: Code metadata (comments, format, hints, ..)
subcommands: cmd_meta

View file

@ -2,6 +2,7 @@ cmd_descs_generate_py = files('cmd_descs_generate.py')
cmd_descs_yaml = files(
'cmd_analysis.yaml',
'cmd_block.yaml',
'cmd_cmp.yaml',
'cmd_debug.yaml',
'cmd_descs.yaml',
'cmd_egg.yaml',

471
librz/core/cmp.c Normal file
View file

@ -0,0 +1,471 @@
// SPDX-FileCopyrightText: 2021 Dhruv Maroo <dhruvmaru007@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_cmp.h>
#include <rz_asm.h>
#include <rz_list.h>
/**
* \brief Compare memory at \p addr1 with the memory at \p addr2
*
* \param core Current RzCore instance
* \param addr1 address to read data from
* \param addr2 address to read data from
* \param len Number of bytes to compare
* \return RzCompareData* A pointer to RzCompareData comparison
*/
RZ_API RZ_OWN RzCompareData *rz_core_cmp_mem_mem(RzCore *core, ut64 addr1, ut64 addr2, ut32 len) {
rz_return_val_if_fail(core, NULL);
ut8 *buf1 = malloc(len * sizeof(ut8));
ut8 *buf2 = malloc(len * sizeof(ut8));
if (!buf1 || !buf2) {
goto error_goto;
}
if (!(rz_io_nread_at(core->io, addr1, buf1, len) == len && rz_io_nread_at(core->io, addr2, buf2, len) == len)) {
RZ_LOG_ERROR("Cannot read %u bytes at provided addresses: 0x%" PFMT64x " 0x%" PFMT64x "\n", len, addr1, addr2);
goto error_goto;
}
RzCompareData *cmp = RZ_NEW0(RzCompareData);
if (!cmp) {
goto error_goto;
}
cmp->len = len;
cmp->data1 = buf1;
cmp->addr1 = addr1;
cmp->data2 = buf2;
cmp->addr2 = addr2;
cmp->same = rz_mem_eq(cmp->data1, cmp->data2, len);
return cmp;
error_goto:
free(buf1);
free(buf2);
return NULL;
}
/**
* \brief Compare mem at \p addr with data \p data
*
* \param core Current RzCore instance
* \param addr address to read data from
* \param data Data to be compared
* \param len Number of bytes to compare
* \return RzCompareData* A pointer to RzCompareData comparison (the data1 corresponds to the data at addr (and addr1 = addr) and data2 is the str data (and addr2 = UT32_MAX))
*/
RZ_API RZ_OWN RzCompareData *rz_core_cmp_mem_data(RzCore *core, ut64 addr, RZ_NONNULL const ut8 *data, ut32 len) {
rz_return_val_if_fail(core && data, NULL);
ut8 *buf1 = malloc(len * sizeof(ut8));
if (!buf1) {
RZ_LOG_ERROR("Cannot read at address: 0x%" PFMT64x "\n", addr);
goto error_goto;
}
if (rz_io_nread_at(core->io, addr, buf1, len) != len) {
RZ_LOG_ERROR("Cannot read %u bytes at provided address: 0x%" PFMT64x "\n", len, addr);
goto error_goto;
}
RzCompareData *cmp = RZ_NEW0(RzCompareData);
if (!cmp) {
goto error_goto;
}
cmp->len = len;
cmp->data1 = buf1;
cmp->addr1 = addr;
cmp->data2 = rz_mem_dup(data, len);
cmp->addr2 = UT64_MAX;
cmp->same = rz_mem_eq(cmp->data1, cmp->data2, len);
return cmp;
error_goto:
free(buf1);
return NULL;
}
/**
* \brief Print a comparison \p cmp according to the print mode \p mode
*
* \param core Current RzCore instance
* \param cmp RzCompareData instance to be printed
* \param state RzCmdStateOutput to be used (options: standard, json) (NULL means standard)
* \return int Number of lines/diffs printed (-1 if failed)
*/
RZ_API int rz_core_cmp_print(RzCore *core, RZ_NONNULL const RzCompareData *cmp, RzCmdStateOutput *state) {
rz_return_val_if_fail(core && cmp, -1);
int i, eq = 0;
bool data_str = cmp->addr2 == UT64_MAX;
if (cmp->len == UT8_MAX) {
return -1;
}
RzOutputMode mode = RZ_OUTPUT_MODE_STANDARD;
PJ *pj = NULL;
if (state) {
mode = state->mode;
pj = state->d.pj;
}
if (mode == RZ_OUTPUT_MODE_JSON) {
pj_o(pj);
pj_k(pj, "diff_bytes");
pj_a(pj);
}
for (i = 0; i < cmp->len; i++) {
if (cmp->data1[i] == cmp->data2[i]) {
eq++;
continue;
}
switch (mode) {
case RZ_OUTPUT_MODE_STANDARD:
rz_cons_printf("0x%08" PFMT64x, cmp->addr1 + i);
if (!data_str) {
rz_cons_printf(" -> 0x%08" PFMT64x, cmp->addr2 + i);
}
rz_cons_printf(" (byte=%.2d) %02x '%c' -> %02x '%c'\n", i + 1,
cmp->data1[i], (IS_PRINTABLE(cmp->data1[i])) ? cmp->data1[i] : ' ',
cmp->data2[i], (IS_PRINTABLE(cmp->data2[i])) ? cmp->data2[i] : ' ');
break;
case RZ_OUTPUT_MODE_JSON:
pj_o(pj);
pj_kn(pj, "offset1", cmp->addr1 + i);
pj_kn(pj, "offset2", data_str ? i : cmp->addr2 + i);
pj_ki(pj, "rel_offset", i);
pj_ki(pj, "value1", (int)cmp->data1[i]);
pj_ki(pj, "value2", (int)cmp->data2[i]);
pj_end(pj);
break;
default:
rz_warn_if_reached();
}
}
if (mode == RZ_OUTPUT_MODE_STANDARD) {
rz_cons_printf("Compare %d/%d equal bytes (%d%%)\n", eq, cmp->len, (int)(100.0 * eq / cmp->len));
} else if (mode == RZ_OUTPUT_MODE_JSON) {
pj_end(pj);
pj_ki(pj, "equal_bytes", eq);
pj_ki(pj, "total_bytes", cmp->len);
pj_end(pj); // End array
pj_end(pj); // End object
}
return cmp->len - eq;
}
/**
* \brief Compare the instructions at \p addr1 and \p addr2
*
* \param core Current RzCore instance
* \param addr1 address to read instructions from
* \param addr2 address to read instructions from
* \param len number of bytes to read instructions from
* \return RzList<RzCompareData>* List of comparison data
*/
RZ_API RZ_OWN RzList /*<RzCompareData>*/ *rz_core_cmp_disasm(RzCore *core, ut64 addr1, ut64 addr2, ut32 len) {
rz_return_val_if_fail(core, NULL);
RzList *cmp_list = rz_list_new();
if (!cmp_list) {
goto error_goto;
}
cmp_list->free = (RzListFree)&rz_core_cmp_free;
RzAsmOp op, op2;
int i, j;
ut8 *buf = calloc(len + 32, 1);
if (!buf) {
goto error_goto;
}
rz_io_nread_at(core->io, addr2, buf, len + 32);
RzCompareData *comp;
for (i = j = 0; i < len && j < len;) {
comp = RZ_NEW0(RzCompareData);
if (!comp) {
continue;
}
// dis A
rz_asm_set_pc(core->rasm, addr1 + i);
(void)rz_asm_disassemble(core->rasm, &op,
core->block + i, len - i);
// dis B
rz_asm_set_pc(core->rasm, addr2 + i);
(void)rz_asm_disassemble(core->rasm, &op2,
buf + j, len - j);
comp->len = UT8_MAX;
comp->data1 = (ut8 *)strdup(rz_strbuf_get(&op.buf_asm));
comp->addr1 = addr1 + i;
comp->data2 = (ut8 *)strdup(rz_strbuf_get(&op2.buf_asm));
comp->addr2 = addr2 + j;
comp->same = !strcmp((char *)comp->data1, (char *)comp->data2); // we can assume that instructions can be represented as plain chars
rz_list_append(cmp_list, comp);
if (op.size < 1) {
op.size = 1;
}
i += op.size;
if (op2.size < 1) {
op2.size = 1;
}
j += op2.size;
}
free(buf);
return cmp_list;
error_goto:
rz_list_free(cmp_list);
return NULL;
}
/**
* \brief Free RzCompareData object
*
* \param cmp RzCompareData object to be freed
* \return void
*/
RZ_API void rz_core_cmp_free(RzCompareData *cmp) {
if (!cmp) {
return;
}
RZ_FREE(cmp->data1);
RZ_FREE(cmp->data2);
free(cmp);
}
/**
* \brief Print the instruction comparison data \p compare
*
* \param core Current RzCore instance
* \param compare list of RzCompareData of instructions
* \param unified print in unified form
* \return bool true if successfull
*/
RZ_API bool rz_core_cmp_disasm_print(RzCore *core, const RzList /*<RzCompareData>*/ *compare, bool unified) {
rz_return_val_if_fail(core && compare, false);
char colpad[80];
int hascolor = rz_config_get_i(core->config, "scr.color");
int cols = rz_config_get_i(core->config, "hex.cols") * 2;
RzConsPrintablePalette *pal = &rz_cons_singleton()->context->pal;
RzListIter *it;
RzCompareData *cmp;
if (unified) {
rz_list_foreach (compare, it, cmp) {
if (cmp->same) {
rz_cons_printf(" 0x%08" PFMT64x " %s\n",
cmp->addr1, cmp->data1);
} else {
if (hascolor) {
rz_cons_print(pal->graph_false);
}
rz_cons_printf("-0x%08" PFMT64x " %s\n",
cmp->addr1, cmp->data1);
if (hascolor) {
rz_cons_print(pal->graph_true);
}
rz_cons_printf("+0x%08" PFMT64x " %s\n",
cmp->addr2, cmp->data2);
if (hascolor) {
rz_cons_print(Color_RESET);
}
}
}
} else {
rz_list_foreach (compare, it, cmp) {
memset(colpad, ' ', sizeof(colpad));
int pos = strlen((char *)cmp->data1);
pos = (pos > cols) ? 0 : cols - pos;
colpad[pos] = 0;
if (hascolor) {
rz_cons_print(cmp->same ? pal->graph_true : pal->graph_false);
}
rz_cons_printf(" 0x%08" PFMT64x " %s %s",
cmp->addr1, cmp->data1, colpad);
rz_cons_printf("%c 0x%08" PFMT64x " %s\n",
cmp->same ? '=' : '!', cmp->addr2, cmp->data2);
if (hascolor) {
rz_cons_print(Color_RESET);
}
}
}
return true;
}
/**
* \defgroup cmpwatch Memory watcher functions API
* API for memory watcher functions
* \{
*/
RZ_API void rz_core_cmpwatch_free(RzCoreCmpWatcher *w) {
if (!w) {
return;
}
free(w->ndata);
free(w->odata);
free(w);
}
/**
* \brief Get the memory watcher at address \p addr
*
* \param core Current RzCore instance
* \param addr Expected address for the memory watcher to be found
* \return RzCoreCmpWatcher* Pointer to the found memory watcher; NULL if not found
*/
RZ_API RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr) {
rz_return_val_if_fail(core, NULL);
RzListIter *iter;
RzCoreCmpWatcher *w;
rz_list_foreach (core->watchers, iter, w) {
if (addr == w->addr) {
return w;
}
}
return NULL;
}
/**
* \brief Add a memory watcher at address \p addr od size \p size and command \p cmd
*
* \param core Current RzCore instance
* \param addr Address where to add the new memory watcher
* \param size Size of the memory watcher to be addded
* \param cmd Command to be associated with the memory watcher
* \return bool true if successful, false otherwise
*/
RZ_API bool rz_core_cmpwatch_add(RzCore *core, ut64 addr, int size, const char *cmd) {
rz_return_val_if_fail(core, false);
RzCoreCmpWatcher *cmpw;
if (size < 1) {
return false;
}
cmpw = rz_core_cmpwatch_get(core, addr);
if (!cmpw) {
cmpw = RZ_NEW(RzCoreCmpWatcher);
if (!cmpw) {
return false;
}
cmpw->addr = addr;
}
cmpw->size = size;
snprintf(cmpw->cmd, sizeof(cmpw->cmd), "%s", cmd);
cmpw->odata = NULL;
cmpw->ndata = malloc(size);
if (!cmpw->ndata) {
free(cmpw);
return false;
}
rz_io_nread_at(core->io, addr, cmpw->ndata, size);
rz_list_append(core->watchers, cmpw);
return true;
}
/**
* \brief Delete a memory watcher at address \p addr
*
* \param core Current RzCore instance
* \param addr Address of the memory watcher to be deleted (if UT64_MAX, then all memory watchers will be deleted)
* \return bool true if found and deleted; false otherwise
*/
RZ_API bool rz_core_cmpwatch_del(RzCore *core, ut64 addr) {
rz_return_val_if_fail(core, false);
int ret = false;
RzCoreCmpWatcher *w;
RzListIter *iter, *iter2;
rz_list_foreach_safe (core->watchers, iter, iter2, w) {
if (w->addr == addr || addr == UT64_MAX) {
rz_list_delete(core->watchers, iter);
ret = true;
}
}
return ret;
}
/**
* \brief Show/print the memory watcher present at address \p addr
*
* \param core Current RzCore instance
* \param addr Address of the memory watcher to be printed (if UT64_MAX, then all memory watchers will be printed)
* \param mode Output mode
* \return void Print nothing if no memory watcher found at \p addr
*/
RZ_API void rz_core_cmpwatch_show(RzCore *core, ut64 addr, RzOutputMode mode) {
rz_return_if_fail(core);
char cmd[128];
RzListIter *iter;
RzCoreCmpWatcher *w;
rz_list_foreach (core->watchers, iter, w) {
if (addr != UT64_MAX && w->addr != addr) {
continue;
}
int is_diff = w->odata ? memcmp(w->odata, w->ndata, w->size) : 0;
switch (mode) {
case RZ_OUTPUT_MODE_RIZIN:
rz_cons_printf("cw 0x%08" PFMT64x " %d %s%s\n",
w->addr, w->size, w->cmd, is_diff ? " # differs" : "");
break;
case RZ_OUTPUT_MODE_STANDARD:
rz_cons_printf("0x%08" PFMT64x "%s\n", w->addr, is_diff ? " modified" : "");
snprintf(cmd, sizeof(cmd), "%s @ %" PFMT64d " @!%d", w->cmd, w->addr, w->size);
rz_core_cmd0(core, cmd);
break;
default:
rz_warn_if_reached();
}
}
}
/**
* \brief Update the memory watcher at address \p addr
*
* \param core Current RzCore instance
* \param addr Address of the memory watcher to be updated (if UT64_MAX, then all memory watchers will be updated)
* \return bool true if any memory watcher was updated; false otherwise
*/
RZ_API bool rz_core_cmpwatch_update(RzCore *core, ut64 addr) {
rz_return_val_if_fail(core, false);
RzCoreCmpWatcher *w;
RzListIter *iter;
bool ret = false;
rz_list_foreach (core->watchers, iter, w) {
if (addr != UT64_MAX && w->addr != addr) {
continue;
}
free(w->odata);
w->odata = w->ndata;
w->ndata = malloc(w->size);
if (!w->ndata) {
return false;
}
rz_io_nread_at(core->io, w->addr, w->ndata, w->size);
ret = true;
}
return ret;
}
/**
* \brief Revert/reset a memory watcher at address \p addr
*
* \param core Current RzCore instance
* \param addr Address of the memory watcher to be reset (if UT64_MAX, then all memory watchers will be reset)
* \return bool true if the memory watcher was resetted; false otherwise
*/
RZ_API bool rz_core_cmpwatch_revert(RzCore *core, ut64 addr) {
rz_return_val_if_fail(core, false);
RzCoreCmpWatcher *w;
int ret = false;
RzListIter *iter;
rz_list_foreach (core->watchers, iter, w) {
if (w->addr == addr || addr == UT64_MAX) {
if (w->odata) {
free(w->ndata);
w->ndata = w->odata;
w->odata = NULL;
ret = true;
}
}
}
return ret;
}
/** \} */

View file

@ -3,6 +3,7 @@
#include <rz_core.h>
#include <rz_socket.h>
#include <rz_cmp.h>
#include <config.h>
#include <rz_util.h>
#if __UNIX__

View file

@ -22,6 +22,7 @@ rz_core_sources = [
'cio.c',
'clang.c',
'cmeta.c',
'cmp.c',
'core.c',
'cparser.c',
'cpdb.c',

51
librz/include/rz_cmp.h Normal file
View file

@ -0,0 +1,51 @@
// SPDX-FileCopyrightText: 2021 Dhruv Maroo <dhruvmaru007@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#ifndef RZ_CMP_H
#define RZ_CMP_H
#include <rz_core.h>
#include <rz_util.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
ut32 len; // max 255 bytes diff in one struct
bool same;
ut8 *data1;
ut8 *data2;
ut64 addr1;
ut64 addr2;
} RzCompareData;
RZ_API RZ_OWN RzCompareData *rz_core_cmp_mem_mem(RzCore *core, ut64 addr1, ut64 addr2, ut32 len);
RZ_API RZ_OWN RzCompareData *rz_core_cmp_mem_data(RzCore *core, ut64 addr, RZ_NONNULL const ut8 *data, ut32 len);
RZ_API int rz_core_cmp_print(RzCore *core, RZ_NONNULL const RzCompareData *cmp, RzCmdStateOutput *state);
RZ_API RZ_OWN RzList /*<RzCompareData>*/ *rz_core_cmp_disasm(RzCore *core, ut64 addr1, ut64 addr2, ut32 len);
RZ_API void rz_core_cmp_free(RzCompareData *cmp);
RZ_API bool rz_core_cmp_disasm_print(RzCore *core, const RzList /*<RzCompareData>*/ *compare, bool unified);
/**
* \struct RzCoreCmpWatcher
* \brief Watcher which executes a command when listed
*/
typedef struct rz_core_cmpwatch_t {
ut64 addr; ///< Address of the watcher
int size; ///< Size of the watcher
char cmd[32]; ///< Command to be executed by the watcher
ut8 *odata; ///< original data at the given address
ut8 *ndata; ///< New data at the given address
} RzCoreCmpWatcher;
/* watchers */
RZ_API void rz_core_cmpwatch_free(RzCoreCmpWatcher *w);
RZ_API RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr);
RZ_API bool rz_core_cmpwatch_add(RzCore *core, ut64 addr, int size, const char *cmd);
RZ_API bool rz_core_cmpwatch_del(RzCore *core, ut64 addr);
RZ_API bool rz_core_cmpwatch_update(RzCore *core, ut64 addr);
RZ_API void rz_core_cmpwatch_show(RzCore *core, ut64 addr, RzOutputMode mode);
RZ_API bool rz_core_cmpwatch_revert(RzCore *core, ut64 addr);
#endif /* RZ_CMP_H */

View file

@ -392,14 +392,6 @@ typedef struct rz_core_item_t {
RZ_API void rz_core_item_free(RzCoreItem *ci);
typedef struct rz_core_cmpwatch_t {
ut64 addr;
int size;
char cmd[32];
ut8 *odata;
ut8 *ndata;
} RzCoreCmpWatcher;
typedef int (*RzCoreSearchCallback)(RzCore *core, ut64 from, ut8 *buf, int len);
#ifdef RZ_API
@ -988,15 +980,6 @@ RZ_API void rz_core_diff_show(RzCore *core, RzCore *core2, bool json);
RZ_API bool rz_core_diff_show_function(RzCore *core, RzCore *core2, ut64 addr, bool json);
RZ_API void rz_core_clippy(RzCore *core, const char *msg);
/* watchers */
RZ_API void rz_core_cmpwatch_free(RzCoreCmpWatcher *w);
RZ_API RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr);
RZ_API int rz_core_cmpwatch_add(RzCore *core, ut64 addr, int size, const char *cmd);
RZ_API int rz_core_cmpwatch_del(RzCore *core, ut64 addr);
RZ_API int rz_core_cmpwatch_update(RzCore *core, ut64 addr);
RZ_API int rz_core_cmpwatch_show(RzCore *core, ut64 addr, int mode);
RZ_API int rz_core_cmpwatch_revert(RzCore *core, ut64 addr);
// TODO MOVE SOMEWHERE ELSE
typedef char *(*PrintItemCallback)(void *user, void *p, bool selected);
RZ_API char *rz_str_widget_list(void *user, RzList *list, int rows, int cur, PrintItemCallback cb);

View file

@ -343,6 +343,7 @@ include_files =[
'include/rz_bind.h',
'include/rz_bp.h',
'include/rz_cmd.h',
'include/rz_cmp.h',
'include/rz_config.h',
'include/rz_cons.h',
'include/rz_core.h',

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@ RUN
NAME="/e /t\wst\d\d\d\s\w\w/i" - oldshell
FILE=malloc://1024
CMDS=<<EOF
cfg.oldshell=true
e cfg.oldshell=true
w "test123 ab"
w "Test123 ab" @ 444
?e
@ -63,4 +63,4 @@ EXPECT=<<EOF
0x00000001 hit0_0 ""test123 ab""
0x000001bd hit0_1 ""Test123 ab""
EOF
RUN
RUN

View file

@ -31,6 +31,7 @@ if get_option('enable_tests')
'bitmap',
'buf',
'cmd',
'compare',
'config',
'cons',
'contrbtree',

91
test/unit/test_compare.c Normal file
View file

@ -0,0 +1,91 @@
// SPDX-FileCopyrightText: 2021 Dhruv Maroo <dhruvmaru007@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_cmp.h>
#include "minunit.h"
char *data =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwx"
"ABCDEFGHIJKLMNOPQRSTUVWX";
char *la = "abcdefghijklmnopqrstuvwxyz";
char *ua = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
bool test_cmp_mem_mem(void) {
RzCore *core = rz_core_new();
rz_io_open(core->io, "malloc://100", RZ_PERM_RW, 0);
rz_io_write(core->io, (ut8 *)data, 100);
RzCompareData *cmp = rz_core_cmp_mem_mem(core, 0, 52, 24);
mu_assert_notnull(cmp, "RzCompareData object null");
mu_assert_eq(cmp->len, 24, "Incorrect length");
mu_assert_eq(cmp->addr1, 0, "Incorrect addr1");
mu_assert_eq(cmp->addr2, 52, "Incorrect addr2");
mu_assert_memeq(cmp->data1, (ut8 *)la, 24, "Memory at offset 0 does not match");
mu_assert_memeq(cmp->data2, (ut8 *)la, 24, "Memory at offset 52 does not match");
mu_assert_eq(cmp->same, true, "Memory not same");
rz_core_cmp_free(cmp);
cmp = rz_core_cmp_mem_mem(core, 0, 26, 26);
mu_assert_notnull(cmp, "RzCompareData object null");
mu_assert_eq(cmp->len, 26, "Incorrect length");
mu_assert_eq(cmp->addr1, 0, "Incorrect addr1");
mu_assert_eq(cmp->addr2, 26, "Incorrect addr2");
mu_assert_memeq(cmp->data1, (ut8 *)la, 26, "Memory at offset 0 does not match");
mu_assert_memeq(cmp->data2, (ut8 *)ua, 26, "Memory at offset 26 does not match");
mu_assert_eq(cmp->same, false, "Memory same");
rz_core_cmp_free(cmp);
cmp = rz_core_cmp_mem_mem(core, 26, 76, 26);
mu_assert_null(cmp, "RzCompareData not null");
rz_core_cmp_free(cmp);
rz_core_free(core);
mu_end;
}
bool test_cmp_mem_data(void) {
RzCore *core = rz_core_new();
rz_io_open(core->io, "malloc://100", RZ_PERM_RW, 0);
rz_io_write(core->io, (ut8 *)data, 100);
RzCompareData *cmp = rz_core_cmp_mem_data(core, 52, (ut8 *)la, 24);
mu_assert_notnull(cmp, "RzCompareData object null");
mu_assert_eq(cmp->len, 24, "Incorrect length");
mu_assert_eq(cmp->addr1, 52, "Incorrect addr1");
mu_assert_eq(cmp->addr2, UT64_MAX, "Incorrect addr2");
mu_assert_memeq(cmp->data1, (ut8 *)la, 24, "Memory at offset 52 does not match");
mu_assert_memeq(cmp->data2, (ut8 *)la, 24, "Data does not match");
mu_assert_eq(cmp->same, true, "Memory not same");
rz_core_cmp_free(cmp);
cmp = rz_core_cmp_mem_data(core, 26, (ut8 *)la, 26);
mu_assert_notnull(cmp, "RzCompareData object null");
mu_assert_eq(cmp->len, 26, "Incorrect length");
mu_assert_eq(cmp->addr1, 26, "Incorrect addr1");
mu_assert_eq(cmp->addr2, UT64_MAX, "Incorrect addr2");
mu_assert_memeq(cmp->data1, (ut8 *)ua, 26, "Memory at offset 26 does not match");
mu_assert_memeq(cmp->data2, (ut8 *)la, 26, "Data does not match");
mu_assert_eq(cmp->same, false, "Memory same");
rz_core_cmp_free(cmp);
cmp = rz_core_cmp_mem_data(core, 76, (ut8 *)ua, 26);
mu_assert_null(cmp, "RzCompareData not null");
rz_core_cmp_free(cmp);
rz_core_free(core);
mu_end;
}
int all_tests() {
mu_run_test(test_cmp_mem_mem);
mu_run_test(test_cmp_mem_data);
return tests_run != tests_passed;
}
mu_main(all_tests);