Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move /a to RzShell #4931

Merged
merged 3 commits into from
Feb 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 76 additions & 70 deletions librz/core/cmd/cmd_search.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "cmd_search_rop.c"
#include "rz_cons.h"
#include <rz_util/rz_mem.h>
#include <rz_util/rz_str_util.h>
#include <rz_util/rz_strbuf.h>
#include <rz_util/rz_regex.h>
Expand Down Expand Up @@ -1903,20 +1904,6 @@ static int cmd_search_legacy_handler(void *data, const char *input) {
__core_cmd_search_asm_byteswap(core, (int)rz_num_math(core->num, input + 2));
} else if (input[1] == 'I') { // "/aI" - infinite
__core_cmd_search_asm_infinite(core, rz_str_trim_head_ro(input + 1));
} else if (input[1] == ' ') {
if (input[param_offset - 1]) {
char *kwd = rz_core_asm_search(core, input + param_offset);
if (!kwd) {
ret = false;
goto beach;
}
dosearch = true;
rz_search_reset(core->search, RZ_SEARCH_KEYWORD);
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
rz_search_kw_add(core->search,
rz_search_keyword_new_hexmask(kwd, NULL));
free(kwd);
}
} else if (input[1] == 's') {
if (input[2] == 'l') { // "asl"
rz_core_cmd0(core, "asl");
Expand Down Expand Up @@ -2523,14 +2510,86 @@ static RzCmdStatus cmd_core_handle_search_hits(RzCore *core, RzCmdStateOutput *s
return RZ_CMD_STATUS_OK;
}

static RzSearchOpt *setup_search_options(RzCore *core) {
RzSearchOpt *search_opts = rz_search_opt_new();
if (!(rz_search_opt_set_max_hits(search_opts, rz_config_get_i(core->config, "search.maxhits")) &&
rz_search_opt_set_max_threads(search_opts, rz_th_max_threads(rz_config_get_i(core->config, "search.max_threads"))))) {
RZ_LOG_ERROR("Failed setup find options.\n");
return NULL;
}

RzSearchFindOpt *fopts = rz_core_setup_default_search_find_opts(core);
if (!fopts) {
RZ_LOG_ERROR("Failed init find options.\n");
return NULL;
}
if (!rz_search_opt_set_find_options(search_opts, fopts)) {
RZ_LOG_ERROR("Failed add find options to the search optoins.\n");
return NULL;
}
return search_opts;
}

static RzCmdStatus byte_pattern_search(RzCore *core, RZ_OWN RzSearchBytesPattern *pattern, RzCmdStateOutput *state) {
RzSearchOpt *search_opts = setup_search_options(core);
RzList *hits = NULL;
if (!search_opts) {
goto error;
}

CMD_SEARCH_BEGIN();

if (!pattern) {
RZ_LOG_ERROR("Failed to parse given pattern.\n");
goto error;
}

bool progress = rz_config_get_b(core->config, "search.show_progress");
if (!rz_search_opt_set_cancel_cb(search_opts, cmd_search_progress_cancel, progress ? state : NULL)) {
RZ_LOG_ERROR("code: Failed to setup default search options.\n");
goto error;
}
hits = rz_core_search_bytes(core, search_opts, pattern);
if (!hits) {
RZ_LOG_ERROR("Failed to perform search.\n");
goto error;
}

CMD_SEARCH_END();
rz_search_opt_free(search_opts);
return cmd_core_handle_search_hits(core, state, hits);

error:
rz_list_free(hits);
rz_search_opt_free(search_opts);
CMD_SEARCH_END();
return RZ_CMD_STATUS_ERROR;
}
// "/+"
RZ_IPI RzCmdStatus rz_cmd_search_str_chunk_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
}

// "/a"
RZ_IPI RzCmdStatus rz_cmd_search_assemble_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
RZ_IPI RzCmdStatus rz_cmd_search_assemble_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
rz_return_val_if_fail(core && core->rasm, RZ_CMD_STATUS_ERROR);
if (!core->rasm->cur) {
RZ_LOG_ERROR("Not RzArch plugin set up.\n");
return RZ_CMD_STATUS_ERROR;
}

RzAsmCode *acode;
if (!(acode = rz_asm_massemble(core->rasm, argv[1]))) {
RZ_LOG_ERROR("Failed to assemble '%s'\n", argv[1]);
RZ_LOG_ERROR("Consider using \"/ar\" instead.\n");
return RZ_CMD_STATUS_ERROR;
}
size_t len = acode->len;
ut8 *bytes = rz_mem_dup(acode->bytes, len);
rz_asm_code_free(acode);

RzSearchBytesPattern *pattern = rz_search_bytes_pattern_new(bytes, NULL, len, "asm_text", false);
return byte_pattern_search(core, pattern, state);
}

// "/a1"
Expand Down Expand Up @@ -2777,64 +2836,11 @@ RZ_IPI RzCmdStatus rz_cmd_search_value_64be_handler(RzCore *core, int argc, cons
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
}

static RzSearchOpt *setup_search_options(RzCore *core) {
RzSearchOpt *search_opts = rz_search_opt_new();
if (!(rz_search_opt_set_max_hits(search_opts, rz_config_get_i(core->config, "search.maxhits")) &&
rz_search_opt_set_max_threads(search_opts, rz_th_max_threads(rz_config_get_i(core->config, "search.max_threads"))))) {
RZ_LOG_ERROR("Failed setup find options.\n");
return NULL;
}

RzSearchFindOpt *fopts = rz_core_setup_default_search_find_opts(core);
if (!fopts) {
RZ_LOG_ERROR("Failed init find options.\n");
return NULL;
}
if (!rz_search_opt_set_find_options(search_opts, fopts)) {
RZ_LOG_ERROR("Failed add find options to the search optoins.\n");
return NULL;
}
return search_opts;
}

// "/x"
RZ_IPI RzCmdStatus rz_cmd_search_hex_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
RzSearchOpt *search_opts = setup_search_options(core);
RzList *hits = NULL;
if (!search_opts) {
goto error;
}

CMD_SEARCH_BEGIN();

const char *arg = argv[1];
RzSearchBytesPattern *pattern = rz_search_parse_byte_pattern(arg, "bytes");

if (!pattern) {
RZ_LOG_ERROR("Failed to parse given pattern.\n");
goto error;
}

bool progress = rz_config_get_b(core->config, "search.show_progress");
if (!rz_search_opt_set_cancel_cb(search_opts, cmd_search_progress_cancel, progress ? state : NULL)) {
RZ_LOG_ERROR("code: Failed to setup default search options.\n");
goto error;
}
hits = rz_core_search_bytes(core, search_opts, pattern);
if (!hits) {
RZ_LOG_ERROR("Failed to perform search.\n");
goto error;
}

CMD_SEARCH_END();
rz_search_opt_free(search_opts);
return cmd_core_handle_search_hits(core, state, hits);

error:
rz_list_free(hits);
rz_search_opt_free(search_opts);
CMD_SEARCH_END();
return RZ_CMD_STATUS_ERROR;
return byte_pattern_search(core, pattern, state);
}

static bool parse_pattern_arg(const char *arg, RZ_OUT ut8 *re, RZ_OUT size_t *len) {
Expand Down
4 changes: 2 additions & 2 deletions librz/core/cmd_descs/cmd_descs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ static const RzCmdDescArg cmd_search_assemble_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_search_assemble_help = {
.summary = "Assemble the instruction and search its bytes",
.summary = "Assemble the instruction and search its bytes.",
.args = cmd_search_assemble_args,
};

Expand Down Expand Up @@ -20836,7 +20836,7 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
rz_warn_if_fail(cmd_search_str_chunk_cd);
rz_cmd_desc_set_default_mode(cmd_search_str_chunk_cd, RZ_OUTPUT_MODE_STANDARD);

RzCmdDesc *slash_a_cd = rz_cmd_desc_group_modes_new(core->rcmd, slash__cd, "/a", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_search_assemble_handler, &cmd_search_assemble_help, &slash_a_help);
RzCmdDesc *slash_a_cd = rz_cmd_desc_group_state_new(core->rcmd, slash__cd, "/a", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_TABLE, rz_cmd_search_assemble_handler, &cmd_search_assemble_help, &slash_a_help);
rz_warn_if_fail(slash_a_cd);
RzCmdDesc *cmd_search_assemble_1_cd = rz_cmd_desc_argv_modes_new(core->rcmd, slash_a_cd, "/a1", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_cmd_search_assemble_1_handler, &cmd_search_assemble_1_help);
rz_warn_if_fail(cmd_search_assemble_1_cd);
Expand Down
2 changes: 1 addition & 1 deletion librz/core/cmd_descs/cmd_descs.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ RZ_IPI RzCmdStatus rz_interpret_macro_multiple_handler(RzCore *core, int argc, c
// "/+"
RZ_IPI RzCmdStatus rz_cmd_search_str_chunk_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
// "/a"
RZ_IPI RzCmdStatus rz_cmd_search_assemble_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
RZ_IPI RzCmdStatus rz_cmd_search_assemble_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
// "/a1"
RZ_IPI RzCmdStatus rz_cmd_search_assemble_1_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
// "/aI"
Expand Down
5 changes: 4 additions & 1 deletion librz/core/cmd_descs/cmd_search.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ commands:
summary: Assemble the instruction and search its bytes.
subcommands:
- name: "/a"
summary: Assemble the instruction and search its bytes
summary: Assemble the instruction and search its bytes.
type: RZ_CMD_DESC_TYPE_ARGV_STATE
cname: cmd_search_assemble
modes:
- RZ_OUTPUT_MODE_STANDARD
- RZ_OUTPUT_MODE_JSON
- RZ_OUTPUT_MODE_QUIET
- RZ_OUTPUT_MODE_TABLE
args:
- name: asm-text
type: RZ_CMD_ARG_TYPE_STRING
Expand Down
4 changes: 0 additions & 4 deletions librz/include/rz_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,9 @@ typedef struct rz_asm_op_t {
} RzAsmOp;

typedef struct rz_asm_code_t {
#if 1
int len;
ut8 *bytes;
char *assembly;
#else
RzAsmOp op; // we have those fields already inside RzAsmOp
#endif
RzList /*<RzAsmEqu *>*/ *equs; // TODO: must be a hash
ut64 code_offset;
ut64 data_offset;
Expand Down
22 changes: 11 additions & 11 deletions test/db/cmd/cmd_search
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ wa "add esp,8;pop ebx; pop ebp; ret"
/a add esp, 8
EOF
EXPECT=<<EOF
0x00000000 hit0_0 83c408
0x00000000 3 hit.asm_text.0
EOF
RUN

Expand All @@ -201,8 +201,8 @@ e search.to=0x50
/a xor al, 0x80
EOF
EXPECT=<<EOF
0x0000003c hit0_0 3480
0x00000040 hit0_1 3480
0x0000003c 2 hit.asm_text.0
0x00000040 2 hit.asm_text.1
EOF
RUN

Expand All @@ -217,19 +217,19 @@ e search.to=0x50
/a xor al, 0x80
EOF
EXPECT=<<EOF
0x0000003c hit0_0 3480
0x00000040 hit0_1 3480
0x0000003c 2 hit.asm_text.0
0x00000040 2 hit.asm_text.1
EOF
RUN

NAME=/a push esp
FILE=bins/elf/ioli/crackme0x00
CMDS=/a push esp
EXPECT=<<EOF
0x08048058 hit0_0 54
0x0804805c hit0_1 54
0x08048060 hit0_2 54
0x08048369 hit0_3 54
0x08048058 1 hit.asm_text.0
0x0804805c 1 hit.asm_text.1
0x08048060 1 hit.asm_text.2
0x08048369 1 hit.asm_text.3
EOF
RUN

Expand Down Expand Up @@ -290,8 +290,8 @@ e search.to=0x00000050
/a xor al, 0x80
EOF
EXPECT=<<EOF
0x0000003c hit0_0 3480
0x00000040 hit0_1 3480
0x0000003c 2 hit.asm_text.0
0x00000040 2 hit.asm_text.1
EOF
RUN

Expand Down
99 changes: 99 additions & 0 deletions test/db/cmd/cmd_search_a
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
NAME=/a search - errors - no assembler
FILE=malloc://1024
CMDS=<<EOF
e asm.arch=hexagon
e asm.bits=32
/a add esp, 8
EOF
EXPECT=
EXPECT_ERR=<<EOF
ERROR: Cannot assemble 'add esp, 8' at line 3
ERROR: Failed to assemble 'add esp, 8'
ERROR: Consider using "/ar" instead.
EOF
RUN

NAME=/a search - errors - faulty asm-text
FILE=malloc://1024
CMDS=<<EOF
e asm.arch=x86.as
e asm.bits=32
wa "add esp,8;pop ebx; pop ebp; ret"
/a ad esp, 8
EOF
EXPECT=
REGEXP_FILTER_ERR=Cannot assemble.*
EXPECT_ERR=<<EOF
Cannot assemble 'ad esp, 8' at line 3
EOF
RUN

NAME=/a search - empty
FILE=
CMDS=<<EOF
e asm.arch=x86.as
e asm.assembler=x86
e asm.bits=32
/a add esp, 8
EOF
EXPECT=<<EOF
EOF
EXPECT_ERR=<<EOF
EOF
RUN

NAME=/a search - x86
FILE=malloc://1024
CMDS=<<EOF
e asm.arch=x86.as
e asm.bits=32
wa "add esp,8;pop ebx; pop ebp; ret"
/a add esp, 8
/a pop ebx
/a pop ebp
/a ret
EOF
EXPECT=<<EOF
0x00000000 3 hit.asm_text.0
0x00000003 1 hit.asm_text.0
0x00000004 1 hit.asm_text.0
0x00000005 1 hit.asm_text.0
EOF
RUN

NAME=/a search - arm - in file
FILE=bins/elf/arm-init
CMDS=<<EOF
/a add r0, pc, r0
pi 1 @ hit.asm_text.0
pi 1 @ hit.asm_text.1
/a pop {fp, pc}
pi 1 @ hit.asm_text.0
pi 1 @ hit.asm_text.1
EOF
EXPECT=<<EOF
0x000002e8 4 hit.asm_text.0
0x00000310 4 hit.asm_text.1
add r0, pc, r0
add r0, pc, r0
0x0000033c 4 hit.asm_text.0
0x0000035c 4 hit.asm_text.1
pop {fp, pc}
pop {fp, pc}
EOF
RUN

NAME=/a search - x86 - in file
FILE=bins/elf/hello_world
CMDS=<<EOF
e asm.arch=x86.as
/a mov r15d, edi
/a hlt
EOF
EXPECT=<<EOF
0x00000854 3 hit.asm_text.0
0x0000028c 1 hit.asm_text.0
0x000006ca 1 hit.asm_text.1
EOF
RUN

Loading
Loading