String/Hex-Search 5/9: Move search commands to RzShell handler.
The commit moves the new and legacy search commands to RzShell, adds more details to the search help, deletes some undocumented or unnecessary commands and adds the stubs for the new search handler implementions. Legacy commands still do their string parsing on arguments and are not touched. The new searches (string and bytes) ahve their actual implementation in the following commmits. Renamed and replaced commands: - Renamed '/' -> '/z' - Replaced '/e' -> '/z' or '/xr' - Replaced '/w' - All Unicode is searched now properly with '/z'. Removed commands: - '/!' - Because the command modifiers are not properly handled in RzShell yet and the advantage of this one is dubious. - '/f' - Modifiers are obsolete, because search is dispatched into threads. - '/b' - Modifiers are obsolete, because search is dispatched into threads. - '/+' - Because no idea what it does. Seems not particular useful. Part 5/9. Likely won't build in between parts. Co-authored-by: wargio <deroad@kumo.xn--q9jyb4c>
This commit is contained in:
parent
1ff3cb99f2
commit
710a33b6ef
9 changed files with 2618 additions and 330 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -359,8 +359,6 @@ jobs:
|
|||
working-directory: rizin
|
||||
- name: Build
|
||||
run: |
|
||||
# Required, otherwise Python3.6 fails with UnicodeDecodeError.
|
||||
export LANG=en_GB.UTF-8
|
||||
meson setup --prefix=/usr build && ninja -C build
|
||||
working-directory: rizin
|
||||
- name: Install
|
||||
|
|
|
|||
|
|
@ -5251,7 +5251,6 @@ RZ_API void rz_core_cmd_init(RzCore *core) {
|
|||
const char *description;
|
||||
RzCmdCb cb;
|
||||
} cmds[] = {
|
||||
{ "/", "search kw, pattern aes", rz_cmd_search },
|
||||
{ "p", "print current block", rz_cmd_print },
|
||||
{ "x", "alias for px", rz_cmd_hexdump },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,123 +2,26 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_asm.h>
|
||||
#include <rz_cmd.h>
|
||||
#include <rz_core.h>
|
||||
#include <rz_io.h>
|
||||
#include <rz_list.h>
|
||||
#include <rz_search.h>
|
||||
#include <rz_types_base.h>
|
||||
#include "../core_private.h"
|
||||
|
||||
#include "cmd_search_rop.c"
|
||||
#include "rz_cons.h"
|
||||
#include <rz_util/rz_str_util.h>
|
||||
#include <rz_util/rz_strbuf.h>
|
||||
#include <rz_util/rz_regex.h>
|
||||
#include <rz_util/rz_str.h>
|
||||
#include <rz_util/rz_assert.h>
|
||||
#include <rz_vector.h>
|
||||
|
||||
#define AES_SEARCH_LENGTH 40
|
||||
#define PRIVATE_KEY_SEARCH_LENGTH 11
|
||||
|
||||
static const char *help_msg_search_esil[] = {
|
||||
"/E", " [esil-expr]", "search offsets matching a specific esil expression",
|
||||
"/Ej", " [esil-expr]", "same as above but using the given magic file",
|
||||
"/E?", " ", "show this help",
|
||||
"\nExamples:", "", "",
|
||||
"", "/E $$,0x100001060,-,!", "hit when address is 0x100001060",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash_m[] = {
|
||||
"/m", "", "search for known magic patterns",
|
||||
"/m", " [file]", "same as above but using the given magic file",
|
||||
"/mb", "", "search recognized RzBin headers",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash[] = {
|
||||
"Usage:", "/[!bf] [arg]", "Search stuff (see 'e??search' for options)\n"
|
||||
"|Use io.va for searching in non virtual addressing spaces",
|
||||
"/", " foo\\x00", "search for string 'foo\\0'",
|
||||
"/j", " foo\\x00", "search for string 'foo\\0' (json output)",
|
||||
"/!", " ff", "search for first occurrence not matching, command modifier",
|
||||
"/!x", " 00", "inverse hexa search (find first byte != 0x00)",
|
||||
"/+", " /bin/sh", "construct the string with chunks",
|
||||
"//", "", "repeat last search",
|
||||
"/a", "[?][1aoditfmsltf] jmp eax", "assemble opcode and search its bytes",
|
||||
"/b", "", "search backwards, command modifier, followed by other command",
|
||||
"/c", "[?][adr]", "search for crypto materials",
|
||||
"/d", " 101112", "search for a deltified sequence of bytes",
|
||||
"/e", " /pattern/[i]", "match regular expression (beginning-of-string for ^ and $ is '\\0')",
|
||||
"/E", " esil-expr", "offset matching given esil expressions $$ = here",
|
||||
"/f", "", "search forwards, (command modifier)",
|
||||
"/F", " file [off] [sz]", "search contents of file with offset and size",
|
||||
// TODO: add subcommands to find paths between functions and filter only function names instead of offsets, etc
|
||||
"/g", "[g] [from]", "find all graph paths A to B (/gg follow jumps, see search.count and analysis.depth)",
|
||||
"/h", "[t] [hash] [len]", "find block matching this hash. See ph",
|
||||
"/i", " foo", "search for string 'foo' ignoring case",
|
||||
"/m", "[?][ebm] magicfile", "search for magic, filesystems or binary headers",
|
||||
"/o", " [n]", "show offset of n instructions backward",
|
||||
"/O", " [n]", "same as /o, but with a different fallback if analysis cannot be used",
|
||||
"/p", " patternsize", "search for pattern of given size",
|
||||
"/P", " patternsize", "search similar blocks",
|
||||
"/s", "[*] [threshold]", "find sections by grouping blocks with similar entropy",
|
||||
"/r[rwx]", "[?] sym.printf", "analyze opcode reference an offset",
|
||||
"/R", " [grepopcode]", "search for matching ROP gadgets, semicolon-separated",
|
||||
// moved into /as "/s", "", "search for all syscalls in a region (EXPERIMENTAL)",
|
||||
"/v", "[1248] value", "look for an `cfg.bigendian` 32bit value",
|
||||
"/V", "[1248] min max", "look for an `cfg.bigendian` 32bit value in range",
|
||||
"/w", " foo", "search for wide string 'f\\0o\\0o\\0'",
|
||||
"/wi", " foo", "search for wide string ignoring case 'f\\0o\\0o\\0'",
|
||||
"/x", " ff..33", "search for hex string ignoring some nibbles",
|
||||
"/x", " ff0033", "search for hex string",
|
||||
"/x", " ff43:ffd0", "search for hexpair with mask",
|
||||
"/z", " min max", "search for strings of given size",
|
||||
"/*", " [comment string]", "add multiline comment, end it with '*/'",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash_a[] = {
|
||||
"Usage:", "/a[?] [arg]", "Search for assembly instructions matching given properties",
|
||||
"/a", " push rbp", "Assemble given instruction and search the bytes",
|
||||
"/a1", " [number]", "Find valid assembly generated by changing only the nth byte",
|
||||
"/aI", "", "Search for infinite loop instructions (jmp $$)",
|
||||
"/aa", " mov eax", "Linearly find aproximated assembly (case insensitive strstr)",
|
||||
"/ac", " mov eax", "Same as /aa, but case-sensitive",
|
||||
"/ad", "[/*j] push;mov", "Match ins1 followed by ins2 in linear disasm",
|
||||
"/ad/", " ins1;ins2", "Search for regex instruction 'ins1' followed by regex 'ins2'",
|
||||
"/ad/a", " instr", "Search for every byte instruction that matches regexp 'instr'",
|
||||
"/ae", " esil", "Search for esil expressions matching substring",
|
||||
"/af", "[l] family", "Search for instruction of specific family (afl=list",
|
||||
"/ai", "[j] 0x300 [0x500]", "Find all the instructions using that immediate (in range)",
|
||||
"/al", "", "Same as aoml, list all opcodes",
|
||||
"/am", " opcode", "Search for specific instructions of specific mnemonic",
|
||||
"/ao", " instr", "Search for instruction 'instr' (in all offsets)",
|
||||
"/as", "[l] ([type])", "Search for syscalls (See /at swi and /af priv)",
|
||||
"/at", "[l] ([type])", "Search for instructions of given type",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash_c[] = {
|
||||
"Usage: /c", "", "Search for crypto materials",
|
||||
"/ca", "", "Search for AES keys expanded in memory",
|
||||
"/cc", "[algo] [digest]", "Find collisions (bruteforce block length values until given checksum is found)",
|
||||
"/cd", "", "Search for ASN1/DER certificates",
|
||||
"/cr", "", "Search for ASN1/DER private keys (RSA and ECC)",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash_r[] = {
|
||||
"Usage:", "/r[acerwx] [address]", " search references to this specific address",
|
||||
"/r", " [addr]", "search references to this specific address",
|
||||
"/ra", "", "search all references",
|
||||
"/rc", "", "search for call references",
|
||||
"/rr", "", "Find read references",
|
||||
"/rw", "", "Find write references",
|
||||
"/rx", "", "Find exec references",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_slash_x[] = {
|
||||
"Usage:", "/x [hexpairs]:[binmask]", "Search in memory",
|
||||
"/x ", "9090cd80", "search for those bytes",
|
||||
"/x ", "9090cd80:ffff7ff0", "search with binary mask",
|
||||
NULL
|
||||
};
|
||||
|
||||
static int preludecnt = 0;
|
||||
static int searchflags = 0;
|
||||
static int searchshow = 0;
|
||||
|
|
@ -619,10 +522,6 @@ static void do_esil_search(RzCore *core, struct search_parameters *param, const
|
|||
param->outmode = RZ_MODE_JSON;
|
||||
input++;
|
||||
}
|
||||
if (input[1] != ' ') { // "/E?"
|
||||
rz_core_cmd_help(core, help_msg_search_esil);
|
||||
return;
|
||||
}
|
||||
if (!core->analysis->esil) {
|
||||
// initialize esil vm
|
||||
rz_core_analysis_esil_reinit(core);
|
||||
|
|
@ -974,9 +873,7 @@ static bool do_analysis_search(RzCore *core, struct search_parameters *param, co
|
|||
type = *input;
|
||||
break;
|
||||
case 0:
|
||||
case '?':
|
||||
default:
|
||||
rz_core_cmd_help(core, help_msg_slash_a);
|
||||
return false;
|
||||
}
|
||||
input++;
|
||||
|
|
@ -1702,6 +1599,7 @@ static void search_collisions(RzCore *core, const char *hashName, const ut8 *has
|
|||
case 'd': // digits
|
||||
incDigitBuffer(buf, bufsz);
|
||||
break;
|
||||
case 'b':
|
||||
default: // binary
|
||||
incBuffer(buf, bufsz);
|
||||
break;
|
||||
|
|
@ -1781,7 +1679,7 @@ static void __core_cmd_search_asm_byteswap(RzCore *core, int nth) {
|
|||
}
|
||||
}
|
||||
|
||||
RZ_IPI int rz_cmd_search(void *data, const char *input) {
|
||||
static int cmd_search_legacy_handler(void *data, const char *input) {
|
||||
bool dosearch = false;
|
||||
int ret = true;
|
||||
RzCore *core = (RzCore *)data;
|
||||
|
|
@ -1798,9 +1696,7 @@ RZ_IPI int rz_cmd_search(void *data, const char *input) {
|
|||
param.cmd_hit = "";
|
||||
}
|
||||
RzSearch *search = core->search;
|
||||
int ignorecase = false;
|
||||
int param_offset = 2;
|
||||
char *inp;
|
||||
if (!core || !core->io) {
|
||||
RZ_LOG_ERROR("core: Can't search if we don't have an open file.\n");
|
||||
return false;
|
||||
|
|
@ -1850,18 +1746,6 @@ RZ_IPI int rz_cmd_search(void *data, const char *input) {
|
|||
param.mode = rz_config_get(core->config, "search.in");
|
||||
param.boundaries = rz_core_get_boundaries_select(core, "search.from", "search.to", "search.in");
|
||||
|
||||
/*
|
||||
this introduces a bug until we implement backwards search
|
||||
for all search types
|
||||
if (__to < __from) {
|
||||
eprintf ("Invalid search range. Check 'e search.{from|to}'\n");
|
||||
return false;
|
||||
}
|
||||
since the backward search will be implemented soon I'm not gonna stick
|
||||
checks for every case in switch // jjdredd
|
||||
remove when everything is done
|
||||
*/
|
||||
|
||||
core->search->align = rz_config_get_i(core->config, "search.align");
|
||||
searchflags = rz_config_get_i(core->config, "search.flags");
|
||||
core->search->maxhits = rz_config_get_i(core->config, "search.maxhits");
|
||||
|
|
@ -1995,15 +1879,10 @@ reread:
|
|||
}
|
||||
}
|
||||
} break;
|
||||
case '?':
|
||||
rz_core_cmd_help(core, help_msg_slash_r);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case 'a': // "/a"
|
||||
if (input[1] == '?') {
|
||||
rz_core_cmd_help(core, help_msg_slash_a);
|
||||
} else if (input[1] == 'd') { // "ad"
|
||||
if (input[1] == 'd') { // "ad"
|
||||
dosearch = 0;
|
||||
do_asm_search(core, ¶m, input + 2, 0, search_itv);
|
||||
} else if (input[1] == 'e') { // "ae"
|
||||
|
|
@ -2146,15 +2025,12 @@ reread:
|
|||
}
|
||||
default: {
|
||||
dosearch = false;
|
||||
rz_core_cmd_help(core, help_msg_slash_c);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case 'm': // "/m"
|
||||
dosearch = false;
|
||||
if (input[1] == '?') { // "/m?"
|
||||
rz_core_cmd_help(core, help_msg_slash_m);
|
||||
} else if (input[1] == 'b') { // "/mb"
|
||||
if (input[1] == 'b') { // "/mb"
|
||||
bool bin_verbose = rz_config_get_i(core->config, "bin.verbose");
|
||||
rz_config_set_i(core->config, "bin.verbose", false);
|
||||
// TODO : iter maps?
|
||||
|
|
@ -2331,106 +2207,6 @@ reread:
|
|||
rz_search_begin(core->search);
|
||||
dosearch = true;
|
||||
break;
|
||||
case 'w': // "/w" search wide string, includes ignorecase search functionality (/wi cmd)!
|
||||
if (input[2]) {
|
||||
if (input[1] == 'j' || input[2] == 'j') {
|
||||
param.outmode = RZ_MODE_JSON;
|
||||
}
|
||||
if (input[1] == 'i' || input[2] == 'i') {
|
||||
ignorecase = true;
|
||||
}
|
||||
} else {
|
||||
param.outmode = RZ_MODE_RIZINCMD;
|
||||
}
|
||||
|
||||
size_t shift = 1 + ignorecase;
|
||||
if (param.outmode == RZ_MODE_JSON) {
|
||||
shift++;
|
||||
}
|
||||
size_t strstart;
|
||||
const char *p2;
|
||||
char *p;
|
||||
strstart = shift + 1;
|
||||
len = strlen(input + strstart);
|
||||
inp = calloc((len + 1), 2);
|
||||
for (p2 = input + strstart, p = inp; *p2; p += 2, p2++) {
|
||||
if (ignorecase) {
|
||||
p[0] = tolower((const ut8)*p2);
|
||||
} else {
|
||||
p[0] = *p2;
|
||||
}
|
||||
p[1] = 0;
|
||||
}
|
||||
rz_search_reset(core->search, RZ_SEARCH_KEYWORD);
|
||||
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
|
||||
RzSearchKeyword *skw;
|
||||
skw = rz_search_keyword_new((const ut8 *)inp, len * 2, NULL, 0, NULL);
|
||||
free(inp);
|
||||
if (skw) {
|
||||
skw->icase = ignorecase;
|
||||
rz_search_kw_add(core->search, skw);
|
||||
rz_search_begin(core->search);
|
||||
dosearch = true;
|
||||
} else {
|
||||
RZ_LOG_ERROR("core: Invalid keyword\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'i': // "/i"
|
||||
if (input[param_offset - 1] != ' ') {
|
||||
RZ_LOG_ERROR("core: Missing ' ' after /i\n");
|
||||
ret = false;
|
||||
goto beach;
|
||||
}
|
||||
ignorecase = true;
|
||||
// fallthrough
|
||||
case 'j': // "/j"
|
||||
if (input[0] == 'j' && input[1] == ' ') {
|
||||
param.outmode = RZ_MODE_JSON;
|
||||
}
|
||||
// fallthrough
|
||||
case ' ': // "/ " search string
|
||||
inp = rz_str_dup(input + 1 + ignorecase + (param.outmode == RZ_MODE_JSON ? 1 : 0));
|
||||
len = rz_str_unescape(inp);
|
||||
rz_search_reset(core->search, RZ_SEARCH_KEYWORD);
|
||||
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
|
||||
{
|
||||
RzSearchKeyword *skw;
|
||||
skw = rz_search_keyword_new((const ut8 *)inp, len, NULL, 0, NULL);
|
||||
free(inp);
|
||||
if (skw) {
|
||||
skw->icase = ignorecase;
|
||||
skw->type = RZ_SEARCH_KEYWORD_TYPE_STRING;
|
||||
rz_search_kw_add(core->search, skw);
|
||||
} else {
|
||||
RZ_LOG_ERROR("core: Invalid keyword\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
rz_search_begin(core->search);
|
||||
dosearch = true;
|
||||
break;
|
||||
case 'e': // "/e" match regexp
|
||||
if (input[1] == '?') {
|
||||
RZ_LOG_ERROR("core: Usage: /e /foo/i or /e/foo/i\n");
|
||||
} else if (input[1]) {
|
||||
RzSearchKeyword *kw;
|
||||
kw = rz_search_keyword_new_regexp(input + 1, NULL);
|
||||
if (!kw) {
|
||||
RZ_LOG_ERROR("core: Invalid regexp specified\n");
|
||||
break;
|
||||
}
|
||||
rz_search_reset(core->search, RZ_SEARCH_REGEXP);
|
||||
// TODO distance is unused
|
||||
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
|
||||
rz_search_kw_add(core->search, kw);
|
||||
rz_search_begin(core->search);
|
||||
dosearch = true;
|
||||
param.regex_search = true;
|
||||
} else {
|
||||
RZ_LOG_ERROR("core: Missing regex\n");
|
||||
}
|
||||
break;
|
||||
case 'E': // "/E"
|
||||
if (core->bin && core->bin->is_debugger) {
|
||||
rz_debug_map_sync(core->dbg);
|
||||
|
|
@ -2562,36 +2338,6 @@ reread:
|
|||
RZ_LOG_ERROR("core: Usage: /F[j] [file] ([offset] ([sz]))\n");
|
||||
}
|
||||
break;
|
||||
case 'x': // "/x" search hex
|
||||
if (!input[1]) {
|
||||
RZ_LOG_ERROR("core: missing hexpairs:binmask\n");
|
||||
break;
|
||||
}
|
||||
if (input[1] == '?') {
|
||||
rz_core_cmd_help(core, help_msg_slash_x);
|
||||
} else {
|
||||
RzSearchKeyword *kw;
|
||||
char *s, *p = rz_str_dup(input + param_offset);
|
||||
rz_search_reset(core->search, RZ_SEARCH_KEYWORD);
|
||||
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
|
||||
s = strchr(p, ':');
|
||||
if (s) {
|
||||
*s++ = 0;
|
||||
kw = rz_search_keyword_new_hex(p, s, NULL);
|
||||
} else {
|
||||
kw = rz_search_keyword_new_hexmask(p, NULL);
|
||||
}
|
||||
if (kw) {
|
||||
rz_search_kw_add(core->search, kw);
|
||||
// eprintf ("Searching %d byte(s)...\n", kw->keyword_length);
|
||||
rz_search_begin(core->search);
|
||||
dosearch = true;
|
||||
} else {
|
||||
RZ_LOG_ERROR("core: no keyword\n");
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
break;
|
||||
case 's': // "/s"
|
||||
do_section_search(core, ¶m, input + 1);
|
||||
break;
|
||||
|
|
@ -2633,39 +2379,6 @@ reread:
|
|||
RZ_LOG_ERROR("core: Usage: /+ [string]\n");
|
||||
}
|
||||
break;
|
||||
case 'z': // "/z" search strings of min-max range
|
||||
{
|
||||
char *p;
|
||||
ut32 min, max;
|
||||
if (!input[1]) {
|
||||
RZ_LOG_ERROR("core: Usage: /z min max\n");
|
||||
break;
|
||||
}
|
||||
if ((p = strchr(input + 2, ' '))) {
|
||||
*p = 0;
|
||||
max = rz_num_math(core->num, p + 1);
|
||||
} else {
|
||||
RZ_LOG_ERROR("core: Usage: /z min max\n");
|
||||
break;
|
||||
}
|
||||
min = rz_num_math(core->num, input + 2);
|
||||
if (!rz_search_set_string_limits(core->search, min, max)) {
|
||||
RZ_LOG_ERROR("core: min must be lower than max\n");
|
||||
break;
|
||||
}
|
||||
rz_search_reset(core->search, RZ_SEARCH_STRING);
|
||||
rz_search_set_distance(core->search, (int)rz_config_get_i(core->config, "search.distance"));
|
||||
{
|
||||
RzSearchKeyword *kw = rz_search_keyword_new_hexmask("00", NULL);
|
||||
kw->type = RZ_SEARCH_KEYWORD_TYPE_STRING;
|
||||
rz_search_kw_add(search, kw);
|
||||
}
|
||||
rz_search_begin(search);
|
||||
dosearch = true;
|
||||
} break;
|
||||
case '?': // "/?"
|
||||
rz_core_cmd_help(core, help_msg_slash);
|
||||
break;
|
||||
default:
|
||||
RZ_LOG_ERROR("core: See /? for help.\n");
|
||||
break;
|
||||
|
|
@ -2686,3 +2399,584 @@ beach:
|
|||
rz_search_kw_reset(search);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pass_to_legacy_api(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
rz_return_val_if_fail(core && argv, RZ_CMD_STATUS_ERROR);
|
||||
// The +1 strips the '/', because the legacy handler expect it this way.
|
||||
const char *cmd = argv[0] + 1;
|
||||
RzStrBuf *legacy_input = rz_strbuf_new(cmd);
|
||||
if (!legacy_input) {
|
||||
rz_warn_if_reached();
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
// Append arguments
|
||||
for (size_t i = 1; i < argc; i++) {
|
||||
rz_strbuf_appendf(legacy_input, " %s", argv[i]);
|
||||
}
|
||||
bool succeeded = cmd_search_legacy_handler(core, rz_strbuf_drain(legacy_input));
|
||||
return succeeded ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
// New search
|
||||
|
||||
#define CMD_SEARCH_BEGIN() \
|
||||
if (core->in_search) { \
|
||||
RZ_LOG_ERROR("core: recursive search is forbidden.\n"); \
|
||||
return RZ_CMD_STATUS_ERROR; \
|
||||
} \
|
||||
rz_cons_break_push(NULL, NULL); \
|
||||
core->in_search = true;
|
||||
|
||||
#define CMD_SEARCH_END() \
|
||||
do { \
|
||||
rz_cons_break_pop(); \
|
||||
core->in_search = false; \
|
||||
} while (0)
|
||||
|
||||
static bool cmd_search_progress_cancel(void *user, size_t n_hits, RzSearchCancelReason invoke_reason) {
|
||||
if (user) {
|
||||
// we have RzCmdStateOutput state
|
||||
rz_cons_printf("Searching... hits: %" PFMTSZu "\r", n_hits);
|
||||
}
|
||||
return rz_cons_is_breaked();
|
||||
}
|
||||
|
||||
static void cmd_search_output_to_state(RzCmdStateOutput *state, RzSearchHit *hit, const char *flag_name) {
|
||||
switch (state->mode) {
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
rz_cons_printf("0x%08" PFMT64x "\n", hit->address);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_STANDARD:
|
||||
rz_cons_printf("0x%08" PFMT64x " %" PFMTSZu " %s\n", hit->address, hit->size, flag_name);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_JSON:
|
||||
pj_o(state->d.pj);
|
||||
pj_kn(state->d.pj, "address", hit->address);
|
||||
pj_kn(state->d.pj, "size", hit->size);
|
||||
pj_ks(state->d.pj, "flag", flag_name);
|
||||
pj_end(state->d.pj);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE:
|
||||
rz_table_add_rowf(state->d.t, "xXs", hit->address, hit->size, flag_name);
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_search_call_command(RzCore *core, RzSearchHit *hit, const char *command) {
|
||||
ut64 old_offset = core->offset;
|
||||
rz_core_seek(core, hit->address, true);
|
||||
rz_core_cmd(core, command, false);
|
||||
rz_core_seek(core, old_offset, true);
|
||||
}
|
||||
|
||||
static RzCmdStatus cmd_core_handle_search_hits(RzCore *core, RzCmdStateOutput *state, RZ_OWN RzList /*<RzSearchHit *>*/ *hits) {
|
||||
if (!hits) {
|
||||
core->num->value = 0;
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
RzListIter *it = NULL;
|
||||
RzSearchHit *hit = NULL;
|
||||
const char *cmd_hit = NULL;
|
||||
const char *search_prefix = NULL;
|
||||
|
||||
cmd_hit = rz_config_get(core->config, "cmd.hit");
|
||||
search_prefix = rz_config_get(core->config, "search.prefix");
|
||||
if (RZ_STR_ISEMPTY(search_prefix)) {
|
||||
// ensure thre prefix is always set.
|
||||
search_prefix = "hit";
|
||||
}
|
||||
|
||||
if (RZ_STR_ISEMPTY(cmd_hit)) {
|
||||
// setup output and flagspace
|
||||
rz_cmd_state_output_array_start(state);
|
||||
rz_cmd_state_output_set_columnsf(state, "xXs", "offset", "size", "flag");
|
||||
rz_flag_space_push(core->flags, "search");
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
rz_list_foreach_enum (hits, it, hit, i) {
|
||||
if (RZ_STR_ISNOTEMPTY(cmd_hit)) {
|
||||
cmd_search_call_command(core, hit, cmd_hit);
|
||||
continue;
|
||||
}
|
||||
|
||||
// only output & add flag when cmd.hit is not set.
|
||||
char *flag = rz_search_hit_flag_name(hit, i, search_prefix);
|
||||
rz_flag_set(core->flags, flag, hit->address, hit->size);
|
||||
cmd_search_output_to_state(state, hit, flag);
|
||||
free(flag);
|
||||
}
|
||||
|
||||
if (RZ_STR_ISEMPTY(cmd_hit)) {
|
||||
// terminating output and flagspace
|
||||
rz_flag_space_pop(core->flags);
|
||||
rz_cmd_state_output_array_end(state);
|
||||
}
|
||||
|
||||
// set return value to the number of hits before returning
|
||||
core->num->value = rz_list_length(hits);
|
||||
rz_list_free(hits);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
// "/+"
|
||||
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);
|
||||
}
|
||||
|
||||
// "/a1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_1_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/aI"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_I_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/aa"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_a_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/ac"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_c_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/ad"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/ad/"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_slash_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ad/a"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_slasha_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ae"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_e_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/af"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_f_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/afl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_fl_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ai"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_i_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/al"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_l_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/am"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_m_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ao"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_o_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/as"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_s_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/asl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_sl_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/at"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_t_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/atl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_tl_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ca"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_aes_key_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, state->mode);
|
||||
}
|
||||
|
||||
// "/cc"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_collision_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/cr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_private_key_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
// "/cd"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_certs_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/d"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_deltified_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/E"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_esil_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/F"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_file_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/g"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_graph_path_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/gg"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_graph_path_follow_jumps_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/h"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_hash_block_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/m"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_magic_const_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
return pass_to_legacy_api(core, argc, argv, mode);
|
||||
}
|
||||
|
||||
// "/mb"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_magic_bin_headers_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/o"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_insn_offset_backwards_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/O"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_insn_offset_backwards_fallback_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/p"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_pattern_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/P"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_blocks_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/r"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/ra"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_all_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/rc"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_call_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/rr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_read_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/rw"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_write_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/rx"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_execute_handler(RzCore *core, int argc, const char **argv) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/s"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_sections_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/v1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/v2"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_16_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/v4"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_32_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/v8"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_64_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/V1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_8be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/V2"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_16be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/V4"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_32be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
return pass_to_legacy_api(core, argc, argv, RZ_OUTPUT_MODE_STANDARD);
|
||||
}
|
||||
|
||||
// "/V8"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_64be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
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;
|
||||
}
|
||||
|
||||
static bool parse_pattern_arg(const char *arg, RZ_OUT ut8 *re, RZ_OUT size_t *len) {
|
||||
*len = 0;
|
||||
size_t arg_len = strlen(arg);
|
||||
// Convert to real bytes.
|
||||
for (size_t i = 0; i < arg_len;) {
|
||||
if (arg[i] == 'x') {
|
||||
if (i + 2 >= arg_len) {
|
||||
RZ_LOG_ERROR("'x' in the pattern must be followed by two hexadecimal nibbles (N = [a-fA-F0-9]): xNN.\n");
|
||||
return false;
|
||||
}
|
||||
if (!IS_HEXCHAR(arg[i + 1]) || !IS_HEXCHAR(arg[i + 2])) {
|
||||
RZ_LOG_ERROR("Bytes with non-hexadecimal nibbles are not allowed. Got: 'x%c%c'.\n", arg[i + 1], arg[i + 2]);
|
||||
return false;
|
||||
}
|
||||
ut16 byte = rz_hex_digit_pair_to_byte(arg + i + 1);
|
||||
re[*len] = byte;
|
||||
i += 3;
|
||||
} else {
|
||||
// Just copy normal character.
|
||||
re[*len] = arg[i];
|
||||
i++;
|
||||
}
|
||||
*len += 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// "/xr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_hex_regex_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
rz_return_val_if_fail(core && state && argv, RZ_CMD_STATUS_ERROR);
|
||||
ut8 *re = RZ_NEWS0(ut8, strlen(argv[1]));
|
||||
RzSearchOpt *search_opts = setup_search_options(core);
|
||||
RzList *hits = NULL;
|
||||
if (!search_opts) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
CMD_SEARCH_BEGIN();
|
||||
|
||||
const char *arg = argv[1];
|
||||
size_t r = 0;
|
||||
if (!parse_pattern_arg(arg, re, &r)) {
|
||||
goto error;
|
||||
}
|
||||
RzSearchBytesPattern *pattern = rz_search_bytes_pattern_new(rz_new_copy(r, re), NULL, r, "bytes", true);
|
||||
|
||||
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();
|
||||
free(re);
|
||||
rz_search_opt_free(search_opts);
|
||||
return cmd_core_handle_search_hits(core, state, hits);
|
||||
|
||||
error:
|
||||
free(re);
|
||||
rz_list_free(hits);
|
||||
rz_search_opt_free(search_opts);
|
||||
CMD_SEARCH_END();
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
static RzCmdStatus cmd_string_search_generic(RzCore *core, const char *string, const char *encoding, RzRegexFlags flags, RzCmdStateOutput *state) {
|
||||
RzSearchOpt *search_opts = setup_search_options(core);
|
||||
if (!search_opts) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
CMD_SEARCH_BEGIN();
|
||||
|
||||
RzStrEnc expected = RZ_STRING_ENC_GUESS;
|
||||
char *search_str = rz_str_dup(string);
|
||||
if (RZ_STR_ISEMPTY(search_str)) {
|
||||
RZ_LOG_ERROR("core: invalid string: empty string.\n");
|
||||
goto invalid_args;
|
||||
}
|
||||
if (RZ_STR_ISEMPTY(encoding)) {
|
||||
RZ_LOG_ERROR("core: invalid encoding: empty encoding.\n");
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
if (rz_str_unescape(search_str) < 1) {
|
||||
RZ_LOG_ERROR("core: invalid string: failed to unescape.\n");
|
||||
goto invalid_args;
|
||||
}
|
||||
|
||||
expected = rz_str_enc_string_as_type(encoding);
|
||||
if (expected == RZ_STRING_ENC_SETTINGS) {
|
||||
expected = rz_str_enc_string_as_type(rz_config_get(core->config, "str.encoding"));
|
||||
}
|
||||
if (!RZ_STR_EQ(encoding, "guess") && expected == RZ_STRING_ENC_GUESS) {
|
||||
if (!RZ_STR_EQ(encoding, "settings")) {
|
||||
RZ_LOG_ERROR("core: invalid encoding '%s'.\n", encoding);
|
||||
goto invalid_args;
|
||||
}
|
||||
// Else we are fine, since the encoding in the settings is set to 'guess'.
|
||||
}
|
||||
|
||||
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");
|
||||
free(search_str);
|
||||
rz_search_opt_free(search_opts);
|
||||
CMD_SEARCH_END();
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzList *hits = rz_core_search_string(core, search_opts, search_str, flags, expected);
|
||||
|
||||
free(search_str);
|
||||
rz_search_opt_free(search_opts);
|
||||
CMD_SEARCH_END();
|
||||
return cmd_core_handle_search_hits(core, state, hits);
|
||||
|
||||
invalid_args:
|
||||
free(search_str);
|
||||
rz_search_opt_free(search_opts);
|
||||
CMD_SEARCH_END();
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
||||
// "/z"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_string_sensitive_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
RzRegexFlags flags = rz_regex_parse_flag_desc(argv[2]);
|
||||
if (flags == ~RZ_REGEX_DEFAULT) {
|
||||
RZ_LOG_ERROR("Regex flags are invalid: '%s'\n", argv[2]);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzCmdStatus res = cmd_string_search_generic(core, argv[1], argv[3], flags, state);
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -61,6 +61,92 @@ RZ_IPI RzCmdStatus rz_interpret_pipe_handler(RzCore *core, int argc, const char
|
|||
RZ_IPI RzCmdStatus rz_interpret_macro_handler(RzCore *core, int argc, const char **argv);
|
||||
// "..("
|
||||
RZ_IPI RzCmdStatus rz_interpret_macro_multiple_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/+"
|
||||
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);
|
||||
// "/a1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_1_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/aI"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_I_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/aa"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_a_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/ac"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_c_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/ad"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/ad/"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_slash_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/ad/a"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_d_slasha_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/ae"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_e_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/af"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_f_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/afl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_fl_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/ai"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_i_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/al"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_l_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/am"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_m_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/ao"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_o_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/as"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_s_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/asl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_sl_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/at"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_t_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/atl"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_assemble_tl_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/ca"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_aes_key_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/cc"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_collision_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/cr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_private_key_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/cd"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_certs_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/d"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_deltified_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/F"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_file_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/o"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_insn_offset_backwards_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/O"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_insn_offset_backwards_fallback_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/p"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_pattern_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/P"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_blocks_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/s"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_sections_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/g"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_graph_path_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/gg"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_graph_path_follow_jumps_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/h"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_hash_block_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/m"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_magic_const_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/mb"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_magic_bin_headers_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/E"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_esil_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
// "/r"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/ra"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_all_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/rc"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_call_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/rr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_read_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/rw"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_write_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/rx"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_reference_execute_handler(RzCore *core, int argc, const char **argv);
|
||||
// "/R"
|
||||
RZ_IPI RzCmdStatus rz_cmd_info_gadget_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/R/"
|
||||
|
|
@ -69,8 +155,28 @@ RZ_IPI RzCmdStatus rz_cmd_search_gadget_handler(RzCore *core, int argc, const ch
|
|||
RZ_IPI RzCmdStatus rz_cmd_query_gadget_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/Rg"
|
||||
RZ_IPI RzCmdStatus rz_cmd_detail_gadget_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/"
|
||||
RZ_IPI int rz_cmd_search(void *data, const char *input);
|
||||
// "/v1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_8_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/v2"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_16_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/v4"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_32_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/v8"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_64_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/V1"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_8be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/V2"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_16be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/V4"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_32be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/V8"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_value_64be_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/x"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_hex_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/xr"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_hex_regex_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "/z"
|
||||
RZ_IPI RzCmdStatus rz_cmd_search_string_sensitive_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
// "R"
|
||||
RZ_IPI RzCmdStatus rz_remote_handler(RzCore *core, int argc, const char **argv);
|
||||
// "R<"
|
||||
|
|
@ -2282,8 +2388,6 @@ RZ_IPI RzCmdStatus rz_seek_redo_handler(RzCore *core, int argc, const char **arg
|
|||
RZ_IPI RzCmdStatus rz_seek_undo_handler(RzCore *core, int argc, const char **argv);
|
||||
// "sh-"
|
||||
RZ_IPI RzCmdStatus rz_seek_undo_reset_handler(RzCore *core, int argc, const char **argv);
|
||||
// "s/"
|
||||
RZ_IPI int rz_seek_search(void *data, const char *input);
|
||||
// "sa"
|
||||
RZ_IPI RzCmdStatus rz_seek_asz_handler(RzCore *core, int argc, const char **argv);
|
||||
// "sb"
|
||||
|
|
|
|||
|
|
@ -148,12 +148,10 @@ commands:
|
|||
- text: "*"
|
||||
arg_str: "entry0"
|
||||
comment: read the value contained at the entrypoint
|
||||
- name: .
|
||||
- name: "."
|
||||
summary: Interpret commands
|
||||
subcommands: cmd_interpret
|
||||
- name: /
|
||||
cname: cmd_search
|
||||
type: RZ_CMD_DESC_TYPE_OLDINPUT
|
||||
- name: "/"
|
||||
summary: Search for bytes, regexps, patterns, ..
|
||||
subcommands: cmd_search
|
||||
- name: "R"
|
||||
|
|
|
|||
|
|
@ -816,7 +816,7 @@ parser.add_argument(
|
|||
parser.add_argument("--output-dir", type=str, required=True, help="Output directory")
|
||||
parser.add_argument(
|
||||
"yaml_files",
|
||||
type=argparse.FileType("r"),
|
||||
type=argparse.FileType("r", encoding="utf8"),
|
||||
nargs="+",
|
||||
help="Input YAML files containing commands descriptions. One should be named 'root'.",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,8 +3,456 @@
|
|||
---
|
||||
name: cmd_search
|
||||
commands:
|
||||
- name: "/+"
|
||||
summary: Construct the string with chunks.
|
||||
cname: cmd_search_str_chunk
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "/bin/sh"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/a"
|
||||
summary: Assemble the instruction and search its bytes.
|
||||
subcommands:
|
||||
- name: "/a"
|
||||
summary: Assemble the instruction and search its bytes
|
||||
cname: cmd_search_assemble
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: asm-text
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/a1"
|
||||
summary: "Find valid assembly generated by changing only the nth byte"
|
||||
cname: cmd_search_assemble_1
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "number"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/aI"
|
||||
summary: "Search for infinite loop instructions (jmp $$)"
|
||||
cname: cmd_search_assemble_I
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args: []
|
||||
- name: "/aa"
|
||||
summary: "Linearly find aproximated assembly (case insensitive strstr)"
|
||||
cname: cmd_search_assemble_a
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "asm-text"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ac"
|
||||
summary: "Same as /aa, but case-sensitive"
|
||||
cname: cmd_search_assemble_c
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "asm-text"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ad"
|
||||
summary: "Match ins1 followed by ins2 in linear disasm"
|
||||
cname: cmd_search_assemble_d
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "mnem;mov"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ad/"
|
||||
summary: "Search for regex instruction 'ins1' followed by regex 'ins2'"
|
||||
cname: cmd_search_assemble_d_slash
|
||||
args:
|
||||
- name: "ins1;ins2"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ad/a"
|
||||
summary: "Search for every byte instruction that matches regexp 'instr'"
|
||||
cname: cmd_search_assemble_d_slasha
|
||||
args:
|
||||
- name: "instr"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ae"
|
||||
summary: "Search for esil expressions matching substring"
|
||||
cname: cmd_search_assemble_e
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "esil"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/af"
|
||||
summary: "Search for instruction of specific family (afl=list"
|
||||
subcommands:
|
||||
- name: "/af"
|
||||
summary: "Search for instruction of specific family (afl=list"
|
||||
cname: cmd_search_assemble_f
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "family"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/afl"
|
||||
summary: "Search for instruction of specific family. List mode."
|
||||
cname: cmd_search_assemble_fl
|
||||
args:
|
||||
- name: "family"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ai"
|
||||
summary: "Find all the instructions using that immediate (in range)"
|
||||
cname: cmd_search_assemble_i
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "0x300"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "0x500"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/al"
|
||||
summary: "Same as aoml, list all opcodes"
|
||||
cname: cmd_search_assemble_l
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args: []
|
||||
- name: "/am"
|
||||
summary: "Search for specific instructions of specific mnemonic"
|
||||
cname: cmd_search_assemble_m
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "opcode"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ao"
|
||||
summary: "Search for instruction 'instr' (in all offsets)"
|
||||
cname: cmd_search_assemble_o
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "instr"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/as"
|
||||
summary: "Search for syscalls (See /at swi and /af priv)"
|
||||
subcommands:
|
||||
- name: "/as"
|
||||
summary: "Search for syscalls (See /at swi and /af priv)"
|
||||
cname: cmd_search_assemble_s
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "type"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/asl"
|
||||
summary: "Search for syscalls (See /at swi and /af priv). List mode."
|
||||
cname: cmd_search_assemble_sl
|
||||
args:
|
||||
- name: "type"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/at"
|
||||
summary: "Search for instructions of given type"
|
||||
subcommands:
|
||||
- name: "/at"
|
||||
summary: "Search for instructions of given type"
|
||||
cname: cmd_search_assemble_t
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: "type"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/atl"
|
||||
summary: "Search for instructions of given type. List mode."
|
||||
cname: cmd_search_assemble_tl
|
||||
args:
|
||||
- name: "type"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/c"
|
||||
summary: Cryptographic material search.
|
||||
subcommands:
|
||||
- name: "/ca"
|
||||
summary: Search for AES keys.
|
||||
cname: cmd_search_aes_key
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args: []
|
||||
- name: "/cc"
|
||||
summary: Find collisions (bruteforce block length values until given checksum is found).
|
||||
cname: cmd_search_collision
|
||||
args:
|
||||
- name: "mode"
|
||||
type: RZ_CMD_ARG_TYPE_CHOICES
|
||||
choices:
|
||||
- "p"
|
||||
- "a"
|
||||
- "A"
|
||||
- "l"
|
||||
- "d"
|
||||
- "b"
|
||||
- name: "algo"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "digest"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
details:
|
||||
- name: Modes
|
||||
entries:
|
||||
- text: a
|
||||
comment: "lowercase alphabet chars only"
|
||||
- text: A
|
||||
comment: "uppercase alphabet chars only"
|
||||
- text: l
|
||||
comment: "letters (lower + upper alphabet chars)"
|
||||
- text: d
|
||||
comment: "digits (only numbers)"
|
||||
- text: p
|
||||
comment: "printable (alpha + digit)"
|
||||
- text: b
|
||||
comment: "binary (any number is valid)"
|
||||
- name: "/cr"
|
||||
summary: Search for private RSA/ECC/EdDSA keys.
|
||||
cname: cmd_search_private_key
|
||||
args: []
|
||||
- name: "/cd"
|
||||
summary: Search for ASN1/DER certificates.
|
||||
cname: cmd_search_certs
|
||||
args: []
|
||||
- name: "/d"
|
||||
summary: Search for a deltified sequence of bytes.
|
||||
cname: cmd_search_deltified
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "101112"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/F"
|
||||
summary: Search contents of file with offset and size.
|
||||
cname: cmd_search_file
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "file"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "offset"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "size"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/o"
|
||||
summary: Show offset of n instructions backward.
|
||||
cname: cmd_search_insn_offset_backwards
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "n"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/O"
|
||||
summary: Same as /o, but with a different fallback if analysis cannot be used.
|
||||
cname: cmd_search_insn_offset_backwards_fallback
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "n"
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/p"
|
||||
summary: Search for pattern of given size.
|
||||
cname: cmd_search_pattern
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "patternsize"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/P"
|
||||
summary: Search similar blocks.
|
||||
cname: cmd_search_blocks
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "patternsize"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/s"
|
||||
summary: Search sections by grouping blocks with similar entropy.
|
||||
cname: cmd_search_sections
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: "threshold"
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
|
||||
- name: "/g"
|
||||
summary: Search for all graph paths A to B (/gg follow jumps, see search.count and analysis.depth).
|
||||
subcommands:
|
||||
- name: "/g"
|
||||
summary: Search for all graph paths A to B (does not follow jumps).
|
||||
cname: cmd_search_graph_path
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: from
|
||||
type: RZ_CMD_ARG_TYPE_RZNUM
|
||||
- name: to
|
||||
type: RZ_CMD_ARG_TYPE_RZNUM
|
||||
- name: "/gg"
|
||||
summary: Search for all graph paths A to B (follow jumps, see `search.count` and `analysis.depth`).
|
||||
cname: cmd_search_graph_path_follow_jumps
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: from
|
||||
type: RZ_CMD_ARG_TYPE_RZNUM
|
||||
- name: to
|
||||
type: RZ_CMD_ARG_TYPE_RZNUM
|
||||
|
||||
- name: "/h"
|
||||
summary: Search for blocks that have the same hash (see also command `ph`).
|
||||
cname: cmd_search_hash_block
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: algo
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: hash
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
details:
|
||||
- name: Usage example
|
||||
entries:
|
||||
- text: "MD5 hash search within blocks of 512 bytes."
|
||||
comment: "/h md5 0bc8f8c426b74ffaedac8330a7464014 @! 512"
|
||||
|
||||
- name: "/m"
|
||||
summary: Magic constants search.
|
||||
subcommands:
|
||||
- name: "/m"
|
||||
summary: Magic constants search.
|
||||
cname: cmd_search_magic_const
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: magic-file
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/mb"
|
||||
summary: Search recognized RzBin headers.
|
||||
cname: cmd_search_magic_bin_headers
|
||||
args: []
|
||||
|
||||
- name: "/E"
|
||||
summary: offset matching given esil expressions $$ = here.
|
||||
cname: cmd_search_esil
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
args:
|
||||
- name: esil-expr
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
|
||||
- name: "/r"
|
||||
summary: Reference search.
|
||||
subcommands:
|
||||
- name: "/r"
|
||||
summary: Reference search.
|
||||
cname: cmd_search_reference
|
||||
args:
|
||||
- name: address
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: "/ra"
|
||||
summary: Search all references.
|
||||
cname: cmd_search_reference_all
|
||||
args: []
|
||||
- name: "/rc"
|
||||
summary: Search call references.
|
||||
cname: cmd_search_reference_call
|
||||
args: []
|
||||
- name: "/rr"
|
||||
summary: Search read references.
|
||||
cname: cmd_search_reference_read
|
||||
args: []
|
||||
- name: "/rw"
|
||||
summary: Search write references.
|
||||
cname: cmd_search_reference_write
|
||||
args: []
|
||||
- name: "/rx"
|
||||
summary: Search execute references.
|
||||
cname: cmd_search_reference_execute
|
||||
args: []
|
||||
|
||||
- name: "/R"
|
||||
summary: List ROP Gadgets
|
||||
summary: Search, List, Query for ROP Gadgets
|
||||
subcommands:
|
||||
- name: "/R"
|
||||
cname: cmd_info_gadget
|
||||
|
|
@ -60,4 +508,293 @@ commands:
|
|||
args:
|
||||
- name: Gadget address
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
optional: true
|
||||
optional: true
|
||||
- name: "/v"
|
||||
summary: Value search.
|
||||
subcommands:
|
||||
- name: "/v1"
|
||||
summary: 8-bit value search.
|
||||
cname: cmd_search_value_8
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value8_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value8_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/v2"
|
||||
summary: 16-bit size value search.
|
||||
cname: cmd_search_value_16
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value16_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value16_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/v4"
|
||||
summary: 32-bit size value search.
|
||||
cname: cmd_search_value_32
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value32_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value32_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/v8"
|
||||
summary: 64-bit size value search.
|
||||
cname: cmd_search_value_64
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value64_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value64_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
details:
|
||||
- name: Usage example
|
||||
entries:
|
||||
- text: "512 value search of its 32-bit representation"
|
||||
comment: "/v4 512"
|
||||
- name: "/V"
|
||||
summary: Value search.
|
||||
subcommands:
|
||||
- name: "/V1"
|
||||
summary: 8-bit value search.
|
||||
cname: cmd_search_value_8be
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value8_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value8_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/V2"
|
||||
summary: 16-bit size value search.
|
||||
cname: cmd_search_value_16be
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value16_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value16_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/V4"
|
||||
summary: 32-bit size value search.
|
||||
cname: cmd_search_value_32be
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value32_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value32_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
|
||||
- name: "/V8"
|
||||
summary: 64-bit size value search.
|
||||
cname: cmd_search_value_64be
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: value64_min
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
- name: value64_max
|
||||
optional: true
|
||||
type: RZ_CMD_ARG_TYPE_NUM
|
||||
details:
|
||||
- name: Usage example
|
||||
entries:
|
||||
- text: "512 value search of its 32-bit representation"
|
||||
comment: "/V4 512"
|
||||
- name: "/x"
|
||||
summary: Raw hexadecimal search.
|
||||
subcommands:
|
||||
- name: "/x"
|
||||
summary: Raw hexadecimal search.
|
||||
cname: cmd_search_hex
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: pattern
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
details:
|
||||
- name: Usage example
|
||||
entries:
|
||||
- text: "Hexadecimal search for the exact bytes 'ffcc33'."
|
||||
comment: "/x ffcc33"
|
||||
- text: "Hexadecimal search for the byte pattern 'ff..33.0.'. The '.' is a wildcard for 4bits."
|
||||
comment: "/x ff..33.0"
|
||||
- text: "Hexadecimal search of the bytes with mask. Pattern: '<resulting bytes>:<mask>'"
|
||||
comment: "/x ffd0:ff43"
|
||||
- text: "Hexadecimal search with an odd number of nibbles."
|
||||
comment: "'aabbc' is equivalent to '.aabbc'"
|
||||
- name: "/xr"
|
||||
summary: Regex bytes search.
|
||||
cname: cmd_search_hex_regex
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: regex_pattern
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
details:
|
||||
- name: Usage examples
|
||||
entries:
|
||||
- text: " Bytes are prefixed with a 'x'. Search exact match '\\x99\\x0a'."
|
||||
comment: "/xr x99x0a"
|
||||
- text: "Search 2-8 NUL bytes, then '\\x99' and '\\x0a'"
|
||||
comment: "/xr x00{2,8}x99x0a"
|
||||
- text: "A '.' matches one byte. Search matches: '\\x72\\xNN\\x00'. '\\xNN' can appear 0-1 times."
|
||||
comment: "/xr x72.?x00"
|
||||
- text: "Using simple ASCII is allowed. Search matches: '\\x61\\x41'"
|
||||
comment: "/xr aA"
|
||||
- name: "/z"
|
||||
summary: String search.
|
||||
details:
|
||||
- name: "Encodings"
|
||||
entries:
|
||||
- text: "ascii"
|
||||
comment: "ASCII encoding"
|
||||
- text: "8bit"
|
||||
comment: "8bit encoding. Alias: ASCII"
|
||||
- text: "mutf8"
|
||||
comment: "mutf8 encoding"
|
||||
- text: "utf8"
|
||||
comment: "UTF-8 encoding"
|
||||
- text: "utf16le"
|
||||
comment: "UTF-16 little endian encoding"
|
||||
- text: "utf32le"
|
||||
comment: "UTF-32 little endian encoding"
|
||||
- text: "utf16be"
|
||||
comment: "UTF-16 big endian encoding"
|
||||
- text: "utf32be"
|
||||
comment: "UTF-32 big endian encoding"
|
||||
- text: "ibm037"
|
||||
comment: "ibm037 encoding. Alias: cp037, ebcdic-cp-us, ebcdic-cp-ca, ebcdic-cp-wt, ebcdic-cp-nl, csIBM037"
|
||||
- text: "ibm290"
|
||||
comment: "ibm290 encoding. Alias: cp290, EBCDIC-JP-kana, csIBM290"
|
||||
- text: "ebcdices"
|
||||
comment: "EBCDIC-ES encoding. Alias: csEBCDICES"
|
||||
- text: "ebcdicuk"
|
||||
comment: "EBCDIC-UK encoding. Alias: csEBCDICUK"
|
||||
- text: "ebcdicus"
|
||||
comment: "EBCDIC-US encoding. Alias: csEBCDICUS"
|
||||
- name: "Regex Flags"
|
||||
entries:
|
||||
- text: "l"
|
||||
comment: "Default. Literal string comparison. Ignores all meta-characters."
|
||||
- text: "i"
|
||||
comment: "Caseless (equivalent: PCRE2_CASELESS)"
|
||||
- text: "r"
|
||||
comment: "Regular expression."
|
||||
- text: "e"
|
||||
comment: "Extended regular expression."
|
||||
- text: "m"
|
||||
comment: "Multiline regular expression (equivalent flag: PCRE2_MULTILINE)"
|
||||
- name: "Exampels"
|
||||
entries:
|
||||
- text: "/z (ABC*)"
|
||||
comment: "Search the exact string \"(ABC*)\"."
|
||||
- text: "/z (ABC*)D li"
|
||||
comment: "Search the exact string \"(ABC*)D\" but case insensitive."
|
||||
- text: "/z \\\\d\\\\sC*\\\\w ri"
|
||||
comment: "Search the regular expression \"\\d\\sC*\\w\" but case insensitive."
|
||||
- text: "/z \"и.{3}м\" ei"
|
||||
comment: "Search the extended regular expression \"и.{3}м\" but case insensitive."
|
||||
subcommands:
|
||||
- name: "/z"
|
||||
summary: String search.
|
||||
cname: cmd_search_string_sensitive
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
default_mode: RZ_OUTPUT_MODE_STANDARD
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
- RZ_OUTPUT_MODE_JSON
|
||||
- RZ_OUTPUT_MODE_QUIET
|
||||
- RZ_OUTPUT_MODE_TABLE
|
||||
args:
|
||||
- name: pattern
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
- name: regex_flags
|
||||
type: RZ_CMD_ARG_TYPE_STRING
|
||||
default_value: "l"
|
||||
- name: encoding
|
||||
type: RZ_CMD_ARG_TYPE_CHOICES
|
||||
default_value: "settings"
|
||||
choices:
|
||||
- "ascii"
|
||||
- "8bit"
|
||||
- "mutf8"
|
||||
- "utf8"
|
||||
- "utf16le"
|
||||
- "utf32le"
|
||||
- "utf16be"
|
||||
- "utf32be"
|
||||
- "ibm037"
|
||||
- "ibm290"
|
||||
- "ebcdices"
|
||||
- "ebcdicuk"
|
||||
- "ebcdicus"
|
||||
- "guess"
|
||||
|
|
|
|||
|
|
@ -67,10 +67,6 @@ commands:
|
|||
cname: seek_undo_reset
|
||||
summary: Clear seek history
|
||||
args: []
|
||||
- name: s/
|
||||
cname: seek_search
|
||||
summary: Seek to the first hit of a search
|
||||
type: RZ_CMD_DESC_TYPE_OLDINPUT
|
||||
- name: sa
|
||||
cname: seek_asz
|
||||
summary: Seek to current offset (or <addr>) aligned to <align>
|
||||
|
|
|
|||
Loading…
Reference in a new issue