Port c commands to newshell (#1854)
Co-authored-by: Riccardo Schirone <ret2libc@users.noreply.github.com>
This commit is contained in:
parent
516c02f0e5
commit
0801f7adf6
18 changed files with 2846 additions and 810 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
169
librz/core/cmd_descs/cmd_cmp.yaml
Normal file
169
librz/core/cmd_descs/cmd_cmp.yaml
Normal 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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
471
librz/core/cmp.c
Normal 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;
|
||||
}
|
||||
/** \} */
|
||||
|
|
@ -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__
|
||||
|
|
|
|||
|
|
@ -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
51
librz/include/rz_cmp.h
Normal 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 */
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
1408
test/db/cmd/cmd_c
1408
test/db/cmd/cmd_c
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ if get_option('enable_tests')
|
|||
'bitmap',
|
||||
'buf',
|
||||
'cmd',
|
||||
'compare',
|
||||
'config',
|
||||
'cons',
|
||||
'contrbtree',
|
||||
|
|
|
|||
91
test/unit/test_compare.c
Normal file
91
test/unit/test_compare.c
Normal 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);
|
||||
Loading…
Reference in a new issue