diff --git a/binrz/rz-test/load.c b/binrz/rz-test/load.c index 1bb7a3e7d6..4a613f6e17 100644 --- a/binrz/rz-test/load.c +++ b/binrz/rz-test/load.c @@ -102,6 +102,43 @@ static char *read_string_val(char **nextline, const char *val, ut64 *linenum) { return strdup(val); } +static const char *rz_test_tools[] = { + "rizin", + "rz-asm", + "rz-ax", + "rz-bin", + "rz-diff", + "rz-find", + "rz-gg", + "rz-hash", + "rz-run", + "rz-sign", + "rz-test", +}; + +RZ_API void rz_test_load_valid_tools(RZ_OUT RZ_NONNULL const char ***tools_o, RZ_OUT RZ_NONNULL size_t *size_o) { + rz_return_if_fail(tools_o && size_o); + + *tools_o = rz_test_tools; + *size_o = RZ_ARRAY_SIZE(rz_test_tools); +} + +static bool is_valid_tool(const char *tool) { + // we always whitelist the tools to avoid malware execution. + if (RZ_STR_ISEMPTY(tool)) { + // rz-test will run rizin or rz-asm + return true; + } + + for (size_t i = 0; i < RZ_ARRAY_SIZE(rz_test_tools); ++i) { + if (RZ_STR_EQ(tool, rz_test_tools[i])) { + return true; + } + } + + return false; +} + RZ_API RzPVector /**/ *rz_test_load_cmd_test_file(const char *file) { char *contents = rz_file_slurp(file, NULL); if (!contents) { @@ -147,8 +184,14 @@ RZ_API RzPVector /**/ *rz_test_load_cmd_test_file(const char *file) // RUN is the only cmd without value if (strcmp(line, "RUN") == 0) { test->run_line = linenum; - if (!test->cmds.value) { - eprintf(LINEFMT "Error: Test without CMDS key\n", file, linenum); + if (RZ_STR_ISEMPTY(test->tool.value) && !test->cmds.value) { + eprintf(LINEFMT "Error: Rizin test without CMDS key\n", file, linenum); + goto fail; + } else if (RZ_STR_ISNOTEMPTY(test->tool.value) && !test->args.value) { + eprintf(LINEFMT "Error: Custom test without ARGS key\n", file, linenum); + goto fail; + } else if (!is_valid_tool(test->tool.value)) { + eprintf(LINEFMT "Error: TOOL key is set to '%s': this is not a valid rizin tool\n", file, linenum, test->tool.value); goto fail; } if (!(test->expect.value || test->expect_err.value)) { diff --git a/binrz/rz-test/run.c b/binrz/rz-test/run.c index dfbb729ce3..389d1b192c 100644 --- a/binrz/rz-test/run.c +++ b/binrz/rz-test/run.c @@ -48,6 +48,9 @@ static RzSubprocessOutput *subprocess_runner(const char *file, const char *args[ #if __WINDOWS__ static char *convert_win_cmds(const char *cmds) { + if (RZ_STR_ISEMPTY(cmds)) { + return NULL; + } char *r = malloc(strlen(cmds) + 1); if (!r) { return NULL; @@ -112,51 +115,159 @@ static char *convert_win_cmds(const char *cmds) { } #endif -static RzSubprocessOutput *run_rz_test(RzTestRunConfig *config, ut64 timeout_ms, const char *cmds, RzList /**/ *files, RzList /**/ *extra_args, bool load_plugins, RzTestCmdRunner runner, void *user) { - RzPVector args; - rz_pvector_init(&args, NULL); - rz_pvector_push(&args, "-escr.utf8=0"); - rz_pvector_push(&args, "-escr.color=0"); - rz_pvector_push(&args, "-escr.interactive=0"); - rz_pvector_push(&args, "-eflirt.sigdb.load.system=false"); - rz_pvector_push(&args, "-esearch.show_progress=false"); - rz_pvector_push(&args, "-eflirt.sigdb.load.home=false"); - rz_pvector_push(&args, "-N"); - RzListIter *it; - void *extra_arg, *file_arg; - rz_list_foreach (extra_args, it, extra_arg) { - rz_pvector_push(&args, extra_arg); +typedef struct run_rz_test_s { + RzTestRunConfig *config; ///< Global configuration + ut64 timeout_ms; ///< Test timeout in millisec + const char *bin_path; ///< Path of the bin directory (can be null) + const char *tool; ///< When set executes a different tool rather than the default exe + const char *cmds; ///< Rizin command line passed as value of `-c` (-q will be added unless TOOL= is defined) + RzList /**/ *envs; ///< Additional environment variables + RzList /**/ *files; ///< Additional files or tool inputs + RzList /**/ *extra_args; ///< Additional arguments + bool load_plugins; ///< When true, allows to load external plugins (RZ_NOPLUGINS=0) + bool color; ///< When true sets RZ_COLOR=1, otherwise RZ_COLOR=0 (default) + bool utf8; ///< When true sets RZ_UTF8=1, otherwise RZ_UTF8=0 (default) + RzTestCmdRunner runner; ///< Function to call to execute the test + void *user; ///< Additional user data passed to `runner`. +} RunRzTest; + +static inline bool run_rz_test_is_custom(const RunRzTest *rrt) { + return RZ_STR_ISNOTEMPTY(rrt->tool); +} + +static void run_rz_test_add_args_from_list(RzPVector /**/ *args, RzList /**/ *list) { + RzListIter *it = NULL; + char *arg = NULL; + rz_list_foreach (list, it, arg) { + if (RZ_STR_ISEMPTY(arg)) { + continue; + } + rz_pvector_push(args, arg); } - rz_pvector_push(&args, "-qc"); -#if __WINDOWS__ - char *wcmds = convert_win_cmds(cmds); - rz_pvector_push(&args, wcmds); -#else - rz_pvector_push(&args, (void *)cmds); -#endif - rz_list_foreach (files, it, file_arg) { - rz_pvector_push(&args, file_arg); +} + +static void run_rz_test_init_args(const RunRzTest *rrt, const char *rizin_cmd, RzPVector /**/ *args) { + rz_pvector_init(args, NULL); + + if (run_rz_test_is_custom(rrt)) { + // the test runs with custom args and may exec a different tool. + run_rz_test_add_args_from_list(args, rrt->extra_args); + if (rizin_cmd) { + rz_pvector_push(args, "-c"); + rz_pvector_push(args, (void *)rizin_cmd); + } + run_rz_test_add_args_from_list(args, rrt->files); + return; } - const char *envvars[] = { + // the test runs in a normal rizin test environment. + rz_pvector_push(args, "-escr.utf8=0"); + rz_pvector_push(args, "-escr.color=0"); + rz_pvector_push(args, "-escr.interactive=0"); + rz_pvector_push(args, "-eflirt.sigdb.load.system=false"); + rz_pvector_push(args, "-esearch.show_progress=false"); + rz_pvector_push(args, "-eflirt.sigdb.load.home=false"); + rz_pvector_push(args, "-N"); + run_rz_test_add_args_from_list(args, rrt->extra_args); + rz_pvector_push(args, "-qc"); + rz_pvector_push(args, (void *)rizin_cmd); + run_rz_test_add_args_from_list(args, rrt->files); +} + +static void run_rz_test_init_envs(const RunRzTest *rrt, const char ***envvars_o, const char ***envvals_o, size_t *env_size_o) { + RzListIter *it = NULL; + char *env = NULL; + size_t env_size = 0; + const size_t reserve = 4 + rz_list_length(rrt->envs); + const char **envvars = RZ_NEWS0(const char *, reserve); + const char **envvals = RZ_NEWS0(const char *, reserve); + +#define RUN_RZ_TEST_ENV_SET(k, v) \ + do { \ + envvars[env_size] = k; \ + envvals[env_size] = v; \ + env_size++; \ + } while (0) + #if __WINDOWS__ - "ANSICON", + RUN_RZ_TEST_ENV_SET("ANSICON", "1"); #endif - "RZ_NOPLUGINS" - }; - const char *envvals[] = { + RUN_RZ_TEST_ENV_SET("RZ_COLOR", rrt->color ? "1" : "0"); + RUN_RZ_TEST_ENV_SET("RZ_UTF8", rrt->utf8 ? "1" : "0"); + if (!rrt->load_plugins) { + RUN_RZ_TEST_ENV_SET("RZ_NOPLUGINS", "1"); + } + + rz_list_foreach (rrt->envs, it, env) { + if (RZ_STR_ISEMPTY(env)) { + continue; + } + + const char *key = env; + char *value = strchr(env, '='); + if (value) { + *value = 0; + RUN_RZ_TEST_ENV_SET(key, value + 1); + } else { + RUN_RZ_TEST_ENV_SET(key, ""); + } + } +#undef RUN_RZ_TEST_ENV_SET + + *envvars_o = envvars; + *envvals_o = envvals; + *env_size_o = env_size; +} + +RZ_API RZ_OWN char *rz_test_find_executable(RZ_NULLABLE const char *exec, RZ_NULLABLE const char *bin_path) { + if (RZ_STR_ISEMPTY(exec)) { + return NULL; + } else if (RZ_STR_ISEMPTY(bin_path)) { + return rz_file_path(exec); + } + #if __WINDOWS__ - "1", -#endif - "1" - }; -#if __WINDOWS__ - size_t env_size = load_plugins ? 1 : 2; + char *exe_path = rz_str_newf(RZ_JOIN_2_PATHS("%s", "%s.exe"), bin_path, exec); #else - size_t env_size = load_plugins ? 0 : 1; + char *exe_path = rz_str_newf(RZ_JOIN_2_PATHS("%s", "%s"), bin_path, exec); #endif - RzSubprocessOutput *out = runner(config->rz_cmd, args.v.a, rz_pvector_len(&args), envvars, envvals, env_size, timeout_ms, user); + + if (rz_file_exists(exe_path)) { + return exe_path; + } + + free(exe_path); + return rz_str_dup(exec); +} + +static char *run_rz_test_find_executable(const RunRzTest *rrt, const char *default_exe) { + const char *exec = default_exe; + if (RZ_STR_ISNOTEMPTY(rrt->tool)) { + exec = rrt->tool; + } + + return rz_test_find_executable(exec, rrt->bin_path); +} + +static RzSubprocessOutput *run_rz_test(const RunRzTest *rrt, const char *default_exe) { + const char **envvars = NULL; + const char **envvals = NULL; + size_t env_size = 0; + RzPVector args; +#if __WINDOWS__ + char *wcmds = convert_win_cmds(rrt->cmds); + run_rz_test_init_args(rrt, wcmds, &args); +#else + run_rz_test_init_args(rrt, rrt->cmds, &args); +#endif + + run_rz_test_init_envs(rrt, &envvars, &envvals, &env_size); + char *executable = run_rz_test_find_executable(rrt, default_exe); + + RzSubprocessOutput *out = rrt->runner(executable, args.v.a, rz_pvector_len(&args), envvars, envvals, env_size, rrt->timeout_ms, rrt->user); rz_pvector_clear(&args); + + free(executable); #if __WINDOWS__ free(wcmds); #endif @@ -166,6 +277,7 @@ static RzSubprocessOutput *run_rz_test(RzTestRunConfig *config, ut64 timeout_ms, RZ_API RzSubprocessOutput *rz_test_run_cmd_test(RzTestRunConfig *config, RzCmdTest *test, RzTestCmdRunner runner, void *user) { RzList *extra_args = test->args.value ? rz_str_split_duplist(test->args.value, " ", true) : NULL; RzList *files = test->file.value ? rz_str_split_duplist(test->file.value, "\n", true) : NULL; + RzList *envs = test->envs.value ? rz_str_split_duplist(test->envs.value, "\n", true) : NULL; RzListIter *it; RzListIter *tmpit; char *token; @@ -179,7 +291,7 @@ RZ_API RzSubprocessOutput *rz_test_run_cmd_test(RzTestRunConfig *config, RzCmdTe rz_list_delete(files, it); } } - if (rz_list_empty(files)) { + if (rz_list_empty(files) && RZ_STR_ISEMPTY(test->tool.value)) { if (!files) { files = rz_list_new(); } else { @@ -188,9 +300,27 @@ RZ_API RzSubprocessOutput *rz_test_run_cmd_test(RzTestRunConfig *config, RzCmdTe rz_list_push(files, "="); } ut64 timeout_ms = test->timeout.set ? test->timeout.value * 1000 : config->timeout_ms; - RzSubprocessOutput *out = run_rz_test(config, timeout_ms, test->cmds.value, files, extra_args, test->load_plugins, runner, user); + + RunRzTest normal_rrt = { + .config = config, + .timeout_ms = timeout_ms, + .bin_path = config->bin_path, + .tool = test->tool.value, + .cmds = test->cmds.value, + .envs = envs, + .files = files, + .extra_args = extra_args, + .load_plugins = test->load_plugins, + .color = test->color.value, + .utf8 = test->utf8.value, + .runner = runner, + .user = user, + }; + + RzSubprocessOutput *out = run_rz_test(&normal_rrt, "rizin"); rz_list_free(extra_args); rz_list_free(files); + rz_list_free(envs); return out; } @@ -227,7 +357,7 @@ RZ_API bool rz_test_cmp_cmd_output(const char *output, const char *expect, const } RZ_API bool rz_test_check_cmd_test(RzSubprocessOutput *out, RzCmdTest *test) { - if (!out || out->ret != 0 || !out->out || !out->err || out->timeout) { + if (!out || out->ret != test->exit_status.value || !out->out || !out->err || out->timeout) { return false; } const char *expect_out = test->expect.value; @@ -248,7 +378,8 @@ RZ_API bool rz_test_check_cmd_test(RzSubprocessOutput *out, RzCmdTest *test) { RZ_API bool rz_test_check_jq_available(void) { const char *args[] = { "." }; const char *invalid_json = "this is not json lol"; - RzSubprocess *proc = rz_subprocess_start(JQ_CMD, args, 1, NULL, NULL, 0); + char *jq_path = rz_file_path(JQ_CMD); + RzSubprocess *proc = rz_subprocess_start(jq_path, args, 1, NULL, NULL, 0); if (proc) { rz_subprocess_stdin_write(proc, (const ut8 *)invalid_json, strlen(invalid_json)); rz_subprocess_wait(proc, UT64_MAX); @@ -257,21 +388,54 @@ RZ_API bool rz_test_check_jq_available(void) { rz_subprocess_free(proc); const char *valid_json = "{\"this is\":\"valid json\",\"lol\":true}"; - proc = rz_subprocess_start(JQ_CMD, args, 1, NULL, NULL, 0); + proc = rz_subprocess_start(jq_path, args, 1, NULL, NULL, 0); if (proc) { rz_subprocess_stdin_write(proc, (const ut8 *)valid_json, strlen(valid_json)); rz_subprocess_wait(proc, UT64_MAX); } bool valid_detected = proc && rz_subprocess_ret(proc) == 0; rz_subprocess_free(proc); - + free(jq_path); return invalid_detected && valid_detected; } +RZ_API bool rz_test_check_tool_available(RZ_NULLABLE const char *exec) { + if (RZ_STR_ISEMPTY(exec)) { + return false; + } + + const char *args[] = { "-v" }; + RzSubprocess *proc = rz_subprocess_start(exec, args, 1, NULL, NULL, 0); + if (!proc) { + return false; + } + rz_subprocess_wait(proc, UT64_MAX); + bool return_zero = rz_subprocess_ret(proc) == 0; + rz_subprocess_free(proc); + + return return_zero; +} + RZ_API RzSubprocessOutput *rz_test_run_json_test(RzTestRunConfig *config, RzJsonTest *test, RzTestCmdRunner runner, void *user) { RzList *files = rz_list_new(); rz_list_push(files, (void *)config->json_test_file); - RzSubprocessOutput *ret = run_rz_test(config, config->timeout_ms, test->cmd, files, NULL, test->load_plugins, runner, user); + + RunRzTest json_rrt = { + .config = config, + .timeout_ms = config->timeout_ms, + .bin_path = config->bin_path, + .tool = NULL, + .cmds = test->cmd, + .files = files, + .extra_args = NULL, + .load_plugins = test->load_plugins, + .color = false, + .utf8 = false, + .runner = runner, + .user = user, + }; + + RzSubprocessOutput *ret = run_rz_test(&json_rrt, "rizin"); rz_list_free(files); return ret; } @@ -281,11 +445,13 @@ RZ_API bool rz_test_check_json_test(RzSubprocessOutput *out, RzJsonTest *test) { return false; } const char *args[] = { "." }; - RzSubprocess *proc = rz_subprocess_start(JQ_CMD, args, 1, NULL, NULL, 0); + char *jq_path = rz_file_path(JQ_CMD); + RzSubprocess *proc = rz_subprocess_start(jq_path, args, 1, NULL, NULL, 0); rz_subprocess_stdin_write(proc, (const ut8 *)out->out, strlen((char *)out->out)); rz_subprocess_wait(proc, UT64_MAX); bool ret = rz_subprocess_ret(proc) == 0; rz_subprocess_free(proc); + free(jq_path); return ret; } @@ -295,6 +461,7 @@ RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest return NULL; } out->as_ret = out->disas_ret = out->il_ret = INT_MAX; + char *rz_asm_exe = rz_file_path("rz-asm"); RzPVector args; rz_pvector_init(&args, NULL); @@ -329,7 +496,7 @@ RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest if (test->mode & RZ_ASM_TEST_MODE_ASSEMBLE) { rz_pvector_push(&args, test->disasm); - RzSubprocess *proc = rz_subprocess_start(config->rz_asm_cmd, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); + RzSubprocess *proc = rz_subprocess_start(rz_asm_exe, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); if (rz_subprocess_wait(proc, config->timeout_ms) == RZ_SUBPROCESS_TIMEDOUT) { rz_subprocess_kill(proc); out->as_timeout = true; @@ -367,7 +534,7 @@ RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest } rz_pvector_push(&args, "-d"); rz_pvector_push(&args, hex); - RzSubprocess *proc = rz_subprocess_start(config->rz_asm_cmd, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); + RzSubprocess *proc = rz_subprocess_start(rz_asm_exe, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); if (rz_subprocess_wait(proc, config->timeout_ms) == RZ_SUBPROCESS_TIMEDOUT) { rz_subprocess_kill(proc); out->disas_timeout = true; @@ -397,7 +564,7 @@ RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest } rz_pvector_push(&args, "-I"); rz_pvector_push(&args, hex); - RzSubprocess *proc = rz_subprocess_start(config->rz_asm_cmd, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); + RzSubprocess *proc = rz_subprocess_start(rz_asm_exe, args.v.a, rz_pvector_len(&args), NULL, NULL, 0); if (rz_subprocess_wait(proc, config->timeout_ms) == RZ_SUBPROCESS_TIMEDOUT) { rz_subprocess_kill(proc); out->il_timeout = true; @@ -419,6 +586,7 @@ RZ_API RzAsmTestOutput *rz_test_run_asm_test(RzTestRunConfig *config, RzAsmTest } beach: + free(rz_asm_exe); rz_pvector_clear(&args); return out; } @@ -478,7 +646,23 @@ RZ_API RzSubprocessOutput *rz_test_run_fuzz_test(RzTestRunConfig *config, RzFuzz cmd = "?F"; } #endif - RzSubprocessOutput *ret = run_rz_test(config, config->timeout_ms, cmd, files, NULL, false, runner, user); + + RunRzTest fuzzer_rrt = { + .config = config, + .timeout_ms = config->timeout_ms, + .bin_path = config->bin_path, + .tool = NULL, + .cmds = cmd, + .files = files, + .extra_args = NULL, + .load_plugins = false, + .color = false, + .utf8 = false, + .runner = runner, + .user = user, + }; + + RzSubprocessOutput *ret = run_rz_test(&fuzzer_rrt, "rizin"); rz_list_free(files); return ret; } diff --git a/binrz/rz-test/rz-test.c b/binrz/rz-test/rz-test.c index c007b1ae42..32c98a3ad3 100644 --- a/binrz/rz-test/rz-test.c +++ b/binrz/rz-test/rz-test.c @@ -80,8 +80,7 @@ static int help(bool verbose) { "-L", "", "Log mode (better printing for CI, logfiles, etc.)", "-F", "dir", "Run fuzz tests (open and default analysis) on all files in the given dir", "-j", "threads", "How many threads to use for running tests concurrently (default is " WORKERS_DEFAULT_STR ")", - "-r", "rizin", "Path to rizin executable (default is " RIZIN_CMD_DEFAULT ")", - "-m", "rz-asm", "Path to rz-asm executable (default is " RZ_ASM_CMD_DEFAULT ")", + "-r", "bindir", "Path to rizin bin folder (default is $PATH)", "-f", "file", "File to use for JSON tests (default is " JSON_TEST_FILE_DEFAULT ")", "-C", "dir", "Chdir before running rz-test (default follows test pathname/cwd)", "-t", "seconds", "Timeout per test (default is " TIMEOUT_DEFAULT_STR " seconds)", @@ -160,6 +159,30 @@ static bool rz_test_chdir_fromtest(const char *test_path) { return found; } +static bool rz_test_can_find_rizin(const char *bin_path) { + char *exec = NULL; + const char **tools = NULL; + size_t count = 0; + rz_test_load_valid_tools(&tools, &count); + + for (size_t i = 0; i < count; ++i) { + exec = rz_test_find_executable(tools[i], bin_path); + + if (RZ_STR_ISEMPTY(exec)) { + eprintf("Cannot find %s in bin path: %s\n", tools[i], bin_path ? bin_path : "$PATH"); + free(exec); + return false; + } else if (!rz_test_check_tool_available(exec)) { + eprintf("%s is not a valid executable\n", exec); + free(exec); + return false; + } + free(exec); + } + + return true; +} + static bool log_mode = false; int rz_test_main(int argc, const char **argv) { @@ -170,8 +193,7 @@ int rz_test_main(int argc, const char **argv) { bool quiet = false; bool interactive = false; bool accept = false; - char *rizin_cmd = NULL; - char *rz_asm_cmd = NULL; + char *bin_path = NULL; char *json_test_file = NULL; char *output_file = NULL; char *fuzz_dir = NULL; @@ -261,8 +283,7 @@ int rz_test_main(int argc, const char **argv) { } break; case 'r': - free(rizin_cmd); - rizin_cmd = strdup(opt.arg); + bin_path = rz_file_abspath(opt.arg); break; case 'C': rz_test_dir = opt.arg; @@ -270,10 +291,6 @@ int rz_test_main(int argc, const char **argv) { case 'n': nothing = true; break; - case 'm': - free(rz_asm_cmd); - rz_asm_cmd = strdup(opt.arg); - break; case 'f': free(json_test_file); json_test_file = strdup(opt.arg); @@ -339,17 +356,16 @@ int rz_test_main(int argc, const char **argv) { } atexit(rz_subprocess_fini); + // this must be done after initializing rz_subprocess + if (!rz_test_can_find_rizin(bin_path)) { + ret = -1; + goto beach; + } + rz_sys_setenv("TZ", "UTC"); ut64 time_start = rz_time_now_mono(); // Avoid PATH search for each process launched - if (!rizin_cmd) { - rizin_cmd = rz_file_path(RIZIN_CMD_DEFAULT); - } - if (!rz_asm_cmd) { - rz_asm_cmd = rz_file_path(RZ_ASM_CMD_DEFAULT); - } - state.run_config.rz_cmd = rizin_cmd; - state.run_config.rz_asm_cmd = rz_asm_cmd; + state.run_config.bin_path = bin_path; state.run_config.json_test_file = json_test_file ? json_test_file : JSON_TEST_FILE_DEFAULT; state.run_config.timeout_ms = timeout_sec > UT64_MAX / 1000 ? UT64_MAX : timeout_sec * 1000; state.verbose = verbose; @@ -599,9 +615,8 @@ coast: rz_test_test_database_free(state.db); ht_sp_free(state.path_left); beach: + free(bin_path); free(output_file); - free(rizin_cmd); - free(rz_asm_cmd); free(json_test_file); free(fuzz_dir); RZ_FREE(cwd); @@ -835,7 +850,7 @@ static void print_result_diff(RzTestRunConfig *config, RzTestResultInfo *result) } else if (*err) { printf("-- stderr\n%s\n", err); } - if (result->proc_out->ret != 0) { + if (result->proc_out->ret != result->test->cmd_test->exit_status.value) { printf("-- exit status: " Color_RED "%d" Color_RESET "\n", result->proc_out->ret); } break; @@ -1257,7 +1272,7 @@ static void replace_cmd_kv_file(const char *path, ut64 line_begin, ut64 line_end static bool interact_fix_cmd(RzTestResultInfo *result, RzPVector /**/ *fixup_results) { assert(result->test->type == RZ_TEST_TYPE_CMD); - if (result->run_failed || result->proc_out->ret != 0) { + if (result->run_failed || result->proc_out->ret != result->test->cmd_test->exit_status.value) { return false; } RzCmdTest *test = result->test->cmd_test; diff --git a/binrz/rz-test/rz_test.h b/binrz/rz-test/rz_test.h index 2f8586a172..0f85d72310 100644 --- a/binrz/rz-test/rz_test.h +++ b/binrz/rz-test/rz_test.h @@ -62,6 +62,8 @@ typedef struct rz_test_cmd_test_t { RzCmdTestStringRecord name; RzCmdTestStringRecord file; RzCmdTestStringRecord args; + RzCmdTestStringRecord tool; + RzCmdTestStringRecord envs; RzCmdTestStringRecord source; RzCmdTestStringRecord cmds; RzCmdTestStringRecord expect; @@ -69,7 +71,10 @@ typedef struct rz_test_cmd_test_t { RzCmdTestStringRecord regexp_out; RzCmdTestStringRecord regexp_err; RzCmdTestBoolRecord broken; + RzCmdTestBoolRecord color; + RzCmdTestBoolRecord utf8; RzCmdTestNumRecord timeout; + RzCmdTestNumRecord exit_status; ut64 run_line; bool load_plugins; } RzCmdTest; @@ -83,14 +88,19 @@ typedef struct rz_test_cmd_test_t { macro_str ("NAME", name) \ macro_str ("FILE", file) \ macro_str ("ARGS", args) \ + macro_str ("TOOL", tool) \ + macro_str ("ENVS", envs) \ macro_int ("TIMEOUT", timeout) \ + macro_int ("EXIT_STATUS", exit_status) \ macro_str ("SOURCE", source) \ macro_str ("CMDS", cmds) \ macro_str ("EXPECT", expect) \ macro_str ("EXPECT_ERR", expect_err) \ macro_str ("REGEXP_FILTER_OUT", regexp_out) \ macro_str ("REGEXP_FILTER_ERR", regexp_err) \ - macro_bool ("BROKEN", broken) + macro_bool ("BROKEN", broken) \ + macro_bool ("COLOR", color) \ + macro_bool ("UTF8", utf8) // clang-format on typedef enum rz_test_asm_test_mode_t { @@ -148,8 +158,7 @@ typedef struct rz_test_test_database_t { } RzTestDatabase; typedef struct rz_test_run_config_t { - const char *rz_cmd; - const char *rz_asm_cmd; + const char *bin_path; const char *json_test_file; ut64 timeout_ms; } RzTestRunConfig; @@ -229,4 +238,8 @@ RZ_API bool rz_test_test_broken(RzTest *test); RZ_API RzTestResultInfo *rz_test_run_test(RzTestRunConfig *config, RzTest *test); RZ_API void rz_test_test_result_info_free(RzTestResultInfo *result); +RZ_API void rz_test_load_valid_tools(RZ_OUT RZ_NONNULL const char ***tools_o, RZ_OUT RZ_NONNULL size_t *size_o); +RZ_API RZ_OWN char *rz_test_find_executable(RZ_NULLABLE const char *exec, RZ_NULLABLE const char *bin_path); +RZ_API bool rz_test_check_tool_available(RZ_NULLABLE const char *exec); + #endif // RIZIN_RZTEST_H diff --git a/librz/bin/p/bin_pe.inc b/librz/bin/p/bin_pe.inc index febf5cfaba..3baff51aa3 100644 --- a/librz/bin/p/bin_pe.inc +++ b/librz/bin/p/bin_pe.inc @@ -624,6 +624,7 @@ static RzPVector /**/ *pe_resources(RzBinFile *bf) { goto err; } br->vaddr = PE_(rz_bin_pe_get_image_base)(obj) + rs->data->OffsetToData; + br->paddr = PE_(bin_pe_rva_to_paddr)(obj, rs->data->OffsetToData); br->size = rs->data->Size; br->type = rz_str_dup(rs->type); if (!br->type) { diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 717eafceca..3eed3afc9a 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -5186,11 +5186,12 @@ static void bin_resources_print_standard(RzCore *core, RzList /**/ *hash rz_cons_printf(" name: %s\n", resource->name); rz_cons_printf(" timestamp: %s\n", resource->time); rz_cons_printf(" vaddr: 0x%08" PFMT64x "\n", resource->vaddr); + rz_cons_printf(" paddr: 0x%08" PFMT64x "\n", resource->paddr); rz_cons_printf(" size: %s\n", humansz); rz_cons_printf(" type: %s\n", resource->type); rz_cons_printf(" language: %s\n", resource->language); if (hashes && resource->size > 0) { - HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->paddr, resource->size, hashes); if (!digests) { return; } @@ -5208,10 +5209,10 @@ static void bin_resources_print_standard(RzCore *core, RzList /**/ *hash } static void bin_resources_print_table(RzCore *core, RzCmdStateOutput *state, RzList /**/ *hashes, RzBinResource *resource) { - rz_table_add_rowf(state->d.t, "dssXxss", resource->index, resource->name, - resource->type, resource->vaddr, resource->size, resource->language, resource->time); + rz_table_add_rowf(state->d.t, "dssXXxss", resource->index, resource->name, + resource->type, resource->vaddr, resource->paddr, resource->size, resource->language, resource->time); if (hashes && resource->size > 0) { - HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->paddr, resource->size, hashes); if (!digests) { return; } @@ -5234,11 +5235,12 @@ static void bin_resources_print_json(RzCore *core, RzCmdStateOutput *state, RzLi pj_ki(state->d.pj, "index", resource->index); pj_ks(state->d.pj, "type", resource->type); pj_kn(state->d.pj, "vaddr", resource->vaddr); + pj_kn(state->d.pj, "paddr", resource->paddr); pj_ki(state->d.pj, "size", resource->size); pj_ks(state->d.pj, "lang", resource->language); pj_ks(state->d.pj, "timestamp", resource->time); if (hashes && resource->size > 0) { - HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->paddr, resource->size, hashes); if (!digests) { goto end; } @@ -5264,7 +5266,7 @@ RZ_API bool rz_core_bin_resources_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBi char *hashname = NULL; rz_cmd_state_output_array_start(state); - rz_cmd_state_output_set_columnsf(state, "dssXxss", "index", "name", "type", "vaddr", "size", "lang", "timestamp"); + rz_cmd_state_output_set_columnsf(state, "dssXXxss", "index", "name", "type", "vaddr", "paddr", "size", "lang", "timestamp"); rz_list_foreach (hashes, it, hashname) { const RzHashPlugin *msg_plugin = rz_hash_plugin_by_name(core->hash, hashname); diff --git a/librz/include/rz_bin.h b/librz/include/rz_bin.h index b7b202bd8d..b80ba07f14 100644 --- a/librz/include/rz_bin.h +++ b/librz/include/rz_bin.h @@ -851,6 +851,7 @@ typedef struct rz_bin_resource_t { char *name; char *time; ut64 vaddr; + ut64 paddr; ut64 size; char *type; char *language; diff --git a/librz/main/rz-bin.c b/librz/main/rz-bin.c index cb1808913c..55ebae6345 100644 --- a/librz/main/rz-bin.c +++ b/librz/main/rz-bin.c @@ -231,6 +231,8 @@ static int rzbin_show_help(int v) { " RZ_BIN_STRPURGE: e bin.str.purge # try to purge false positives\n" " RZ_BIN_SYMSTORE: e pdb.symstore # path to downstream PDB symbol store\n" " RZ_CONFIG: # config file\n" + " RZ_COLOR: # enables/disables colors support\n" + " RZ_UTF8: # enables/disables utf8 support\n" " RZ_NOPLUGINS: # do not load plugins\n"); } return 1; @@ -782,6 +784,14 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) { rz_config_set(core.config, "pdb.server", tmp); free(tmp); } + if ((tmp = rz_sys_getenv("RZ_COLOR"))) { + rz_config_set(core.config, "scr.color", tmp); + free(tmp); + } + if ((tmp = rz_sys_getenv("RZ_UTF8"))) { + rz_config_set(core.config, "scr.utf8", tmp); + free(tmp); + } #define is_active(x) (action & (x)) #define set_action(x) \ @@ -1313,6 +1323,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) { } ut32 mask = actions2mask(action); + rz_core_bin_apply_config(&core, bf); rz_core_bin_print(&core, bf, mask, &filter, &state, chksum_list); run_action("classes source", RZ_BIN_REQ_CLASSES_SOURCES, classes_as_source_print); diff --git a/librz/main/rz-diff.c b/librz/main/rz-diff.c index 592580d89e..0ef9fdc4b7 100644 --- a/librz/main/rz-diff.c +++ b/librz/main/rz-diff.c @@ -205,17 +205,16 @@ static void rz_diff_show_help(bool usage_only) { // clang-format off "-a", "arch", "Specify architecture plugin to use (x86, arm, ..)", "-b", "bits", "Specify register size for arch (16 (thumb), 32, 64, ..)", - "-d", "algo", "Compute edit distance based on the chosen algorithm:", - "", "", " myers | Eugene W. Myers' O(ND) algorithm (no substitution)", - "", "", " leven | Levenshtein O(N^2) algorithm (with substitution)", - "", "", " ssdeep | Context triggered piecewise hashing comparison", + "-d", "myers", "Compute edit distance using Eugene W. Myers' O(ND) algorithm (no substitution)", + "-d", "leven", "Compute edit distance using Levenshtein O(N^2) algorithm (with substitution)", + "-d", "ssdeep", "Compute edit distance using Context triggered piecewise hashing comparison", "-i", "", "Use command line arguments instead of files (only for -d)", "-H", "", "Hexadecimal visual mode", "-h", "", "Show this help", "-j", "", "JSON output", "-q", "", "Quiet output", - "-V", "", "Show version information", - "-v", "", "Be more verbose (stderr output)", + "-v", "", "Show version information", + "-V", "", "Be more verbose (stderr output)", "-K", "theme", "Set a give color theme (see rizin 'eco' command)", "-e", "k=v", "Set an evaluable config variable", "-A", "", "Compare virtual and physical addresses", @@ -226,32 +225,32 @@ static void rz_diff_show_help(bool usage_only) { "-0", "cmd", "Input for file0 when option -t 'commands' is given.", "", "", "The same value will be set for file1, if -1 is not set.", "-1", "cmd", "Input for file1 when option -t 'commands' is given.", - "-t", "type", "Compute the difference between two files based on its type:", - "", "", " bytes | compare raw bytes in the files (only for small files)", - "", "", " lines | compare text files", - "", "", " functions | compare functions found in the files", - "", "", " | optional -0 to compare only one function", - "", "", " classes | compare classes found in the files", - "", "", " command | compare command output returned when executed in both files", - "", "", " | require -0 and -1 is optional", - "", "", " entries | compare entries found in the files", - "", "", " fields | compare fields found in the files", - "", "", " graphs | compare 2 functions and outputs in graphviz/dot format", - "", "", " | require -0 and -1 is optional", - "", "", " imports | compare imports found in the files", - "", "", " libraries | compare libraries found in the files", - "", "", " sections | compare sections found in the files", - "", "", " strings | compare strings found in the files", - "", "", " symbols | compare symbols found in the files", + "-t", "bytes", "Compare raw bytes in the files (only for small files)", + "-t", "lines", "Compare text files", + "-t", "functions", "Compare functions found in the files", + "", "", "optional -0 to compare only one function", + "-t", "classes", "Compare classes found in the files", + "-t", "command", "Compare command output returned when executed in both files", + "", "", "requires -0 and -1 is optional", + "-t", "entries", "Compare entries found in the files", + "-t", "fields", "Compare fields found in the files", + "-t", "graphs", "Compare 2 functions and outputs in graphviz/dot format", + "", "", "requires -0 and -1 is optional", + "-t", "imports", "Compare imports found in the files", + "-t", "libraries", "Compare libraries found in the files", + "-t", "sections", "Compare sections found in the files", + "-t", "strings", "Compare strings found in the files", + "-t", "symbols", "Compare symbols found in the files", // clang-format on }; rz_print_colored_help(options, RZ_ARRAY_SIZE(options), false); printf( - "palette colors can be changed by adding the following lines\n" - "inside the $HOME/.rizinrc file\n" - "ec diff.unknown blue | offset color\n" - "ec diff.match green | match color\n" - "ec diff.unmatch red | mismatch color\n"); + "Palette colors can be changed by adding the following lines inside the $HOME/.rizinrc file\n" + " ec diff.unknown blue | offset color\n" + " ec diff.match green | match color\n" + " ec diff.unmatch red | mismatch color\n" + "Environment variables\n" + " RZ_COLOR | enables/disables colors support\n"); } static bool rz_diff_is_file(const char *file) { @@ -264,12 +263,22 @@ static bool rz_diff_is_file(const char *file) { return true; } +static bool diff_env_get_bool(const char *key, bool def_value) { + bool value = def_value; + char *tmp = rz_sys_getenv(key); + if (RZ_STR_ISNOTEMPTY(tmp)) { + value = rz_num_get(NULL, tmp) != 0; + } + free(tmp); + return value; +} + static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ctx) { const char *type = NULL; const char *algorithm = NULL; const char *screen = NULL; memset((void *)ctx, 0, sizeof(DiffContext)); - ctx->colors = true; + ctx->colors = diff_env_get_bool("RZ_COLOR", true); ctx->evars = rz_list_newf(free); if (!ctx->evars) { @@ -286,7 +295,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct case '1': rz_diff_ctx_set_def(ctx, input_b, NULL, opt.arg); break; case 'A': rz_diff_ctx_set_def(ctx, compare_addresses, false, true); break; case 'B': rz_diff_ctx_set_def(ctx, analyze_all, false, true); break; - case 'C': rz_diff_ctx_set_def(ctx, colors, true, false); break; + case 'C': rz_diff_ctx_set_def(ctx, colors, ctx->colors, false); break; case 'T': rz_diff_ctx_set_def(ctx, show_time, false, true); break; case 'a': rz_diff_ctx_set_def(ctx, architecture, NULL, opt.arg); break; case 'b': rz_diff_ctx_set_unsigned(ctx, arch_bits, opt.arg); break; @@ -296,8 +305,8 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct case 'j': rz_diff_ctx_set_mode(ctx, DIFF_MODE_JSON); break; case 'q': rz_diff_ctx_set_mode(ctx, DIFF_MODE_QUIET); break; case 't': rz_diff_set_def(type, NULL, opt.arg); break; - case 'V': rz_diff_ctx_set_opt(ctx, DIFF_OPT_VERSION); break; - case 'v': rz_diff_ctx_set_def(ctx, verbose, false, true); break; + case 'v': rz_diff_ctx_set_opt(ctx, DIFF_OPT_VERSION); break; + case 'V': rz_diff_ctx_set_def(ctx, verbose, false, true); break; case 'S': rz_diff_set_def(screen, NULL, opt.arg); break; case 'H': rz_diff_ctx_set_opt(ctx, DIFF_OPT_HEX_VISUAL); break; case 'e': rz_diff_ctx_add_evar(ctx, opt.arg); break; diff --git a/librz/main/rz-run.c b/librz/main/rz-run.c index ef48908ac0..3e3a2530bc 100644 --- a/librz/main/rz-run.c +++ b/librz/main/rz-run.c @@ -140,51 +140,41 @@ static void rz_run_help(int v) { } } +static RzRunProfile *rz_run_new_from_cmdline(int start, int argc, const char **argv) { + bool no_more_directives = false; + int directive_index = 0; + RzRunProfile *p = rz_run_new(NULL); + if (!p) { + RZ_LOG_ERROR("Failed to create new RzRunProfile\n"); + return NULL; + } + for (int i = start; i < argc; i++) { + if (!strcmp(argv[i], "--")) { + no_more_directives = true; + continue; + } + if (no_more_directives) { + const char *word = argv[i]; + char *line = directive_index + ? rz_str_newf("arg%d=%s", directive_index, word) + : rz_str_newf("program=%s", word); + rz_run_parseline(p, line); + directive_index++; + free(line); + } else if (!rz_run_parseline(p, argv[i])) { + goto fail; + } + } + return p; + +fail: + rz_run_free(p); + return NULL; +} RZ_API int rz_main_rz_run(int argc, const char **argv) { - RzRunProfile *p; - int i, ret; - const char *file = argv[1]; - if (!strcmp(file, "-w")) { -#if __UNIX__ - rz_run_tty(); - return 0; -#else - RZ_LOG_ERROR("Not supported\n"); - return 1; -#endif - } - if (*file && !strchr(file, '=')) { - p = rz_run_new(file); - } else { - bool noMoreDirectives = false; - int directiveIndex = 0; - p = rz_run_new(NULL); - if (!p) { - RZ_LOG_ERROR("Failed to create new RzRunProfile\n"); - return 1; - } - for (i = *file ? 1 : 2; i < argc; i++) { - if (!strcmp(argv[i], "--")) { - noMoreDirectives = true; - continue; - } - if (noMoreDirectives) { - const char *word = argv[i]; - char *line = directiveIndex - ? rz_str_newf("arg%d=%s", directiveIndex, word) - : rz_str_newf("program=%s", word); - rz_run_parseline(p, line); - directiveIndex++; - free(line); - } else { - rz_run_parseline(p, argv[i]); - } - } - } - if (!p) { - return 1; - } + int ret = 0; + RzRunProfile *p = NULL; if (argc == 1 || !strcmp(argv[1], "-h")) { rz_run_help(0); ret = 1; @@ -210,6 +200,24 @@ RZ_API int rz_main_rz_run(int argc, const char **argv) { ret = 0; goto finish; } + const char *file = argc > 1 ? argv[1] : ""; + if (RZ_STR_ISNOTEMPTY(file) && !strcmp(file, "-w")) { +#if __UNIX__ + rz_run_tty(); + return 0; +#else + RZ_LOG_ERROR("Not supported\n"); + return 1; +#endif + } + if (RZ_STR_ISNOTEMPTY(file) && !strchr(file, '=')) { + p = rz_run_new(file); + } else { + p = rz_run_new_from_cmdline(*file ? 1 : 2, argc, argv); + } + if (!p) { + return 1; + } ret = rz_run_config_env(p); if (ret) { printf("error while configuring the environment.\n"); diff --git a/librz/socket/run.c b/librz/socket/run.c index e935e720ba..3dc0ecd7a7 100644 --- a/librz/socket/run.c +++ b/librz/socket/run.c @@ -77,13 +77,17 @@ static void dyn_init(void) { RZ_API RzRunProfile *rz_run_new(const char *str) { RzRunProfile *p = RZ_NEW0(RzRunProfile); - if (p) { - rz_run_reset(p); - if (str) { - rz_run_parsefile(p, str); - } + if (!p) { + return NULL; } - return p; + rz_run_reset(p); + + if (!str || rz_run_parsefile(p, str)) { + return p; + } + + rz_run_free(p); + return NULL; } RZ_API void rz_run_reset(RzRunProfile *p) { @@ -104,7 +108,10 @@ RZ_API bool rz_run_parse(RzRunProfile *pf, const char *profile) { if ((o = strchr(p, '\n'))) { *o++ = 0; } - rz_run_parseline(pf, p); + if (!rz_run_parseline(pf, p)) { + free(str); + return false; + } p = o; } free(str); @@ -112,22 +119,23 @@ RZ_API bool rz_run_parse(RzRunProfile *pf, const char *profile) { } RZ_API void rz_run_free(RzRunProfile *r) { - if (r) { - free(r->_system); - free(r->_program); - free(r->_runlib); - free(r->_runlib_fcn); - free(r->_stdio); - free(r->_stdin); - free(r->_stdout); - free(r->_stderr); - free(r->_chgdir); - free(r->_chroot); - free(r->_libpath); - free(r->_preload); - free(r->_input); - free(r); + if (!r) { + return; } + free(r->_system); + free(r->_program); + free(r->_runlib); + free(r->_runlib_fcn); + free(r->_stdio); + free(r->_stdin); + free(r->_stdout); + free(r->_stderr); + free(r->_chgdir); + free(r->_chroot); + free(r->_libpath); + free(r->_preload); + free(r->_input); + free(r); } #if __UNIX__ @@ -597,7 +605,13 @@ RZ_API bool rz_run_parseline(RzRunProfile *p, const char *b) { } else if (!memcmp(b, "arg", 3)) { int n = atoi(b + 3); if (n >= 0 && n < RZ_RUN_PROFILE_NARGS) { - p->_args[n] = resolve_value(value, NULL); + char *arg_n = resolve_value(value, NULL); + if (!arg_n) { + free(key); + free(value); + return false; + } + p->_args[n] = arg_n; p->_argc++; } else { RZ_LOG_ERROR("rz-run: out of bounds args index: %d\n", n); diff --git a/librz/util/str.c b/librz/util/str.c index 5332b540c9..6ca2bbb57d 100644 --- a/librz/util/str.c +++ b/librz/util/str.c @@ -1947,13 +1947,14 @@ RZ_API char *rz_str_escape_mutf8_for_json(const char *buf, int buf_size) { RZ_API RZ_OWN char *rz_str_format_msvc_argv(size_t argc, const char **argv) { RzStrBuf sb; rz_strbuf_init(&sb); - - size_t i; - for (i = 0; i < argc; i++) { - if (i > 0) { + for (size_t i = 0; i < argc; i++) { + const char *arg = argv[i]; + if (!arg) { + arg = ""; + } + if (!rz_strbuf_is_empty(&sb)) { rz_strbuf_append(&sb, " "); } - const char *arg = argv[i]; bool must_escape = strchr(arg, '\"') != NULL; bool must_quote = strpbrk(arg, " \t") != NULL || !*arg; if (!must_escape && must_quote && *arg && arg[strlen(arg) - 1] == '\\') { diff --git a/test/README.md b/test/README.md index 221505373e..1c047ab910 100644 --- a/test/README.md +++ b/test/README.md @@ -189,9 +189,14 @@ Without the regex that filtered out the non-deterministic file path and addresse ``` * **NAME** is the name of the test, it must be unique -* **FILE** is the path of the file used for the test -* **ARGS** (optional) are the command line argument passed to rizin (e.g -b 16) +* **FILE** (optional when `TOOL` is set) is the file or input used for the test +* **TOOL** (optional) allows you to override the tool to test (supports only `rizin`, `rz-asm`, `rz-ax`, `rz-bin`, `rz-diff`, `rz-find`, `rz-gg`, `rz-hash`, `rz-run`, `rz-sign`, `rz-test`) +* **ARGS** (optional, unless `TOOL` is set) are the command line argument passed to rizin (e.g -b 16) * **CMDS** are the commands to be executed by the test +* **ENVS** (optional) allows to set a custom environment variable (example `FOO=bar`) +* **EXIT_STATUS** (optional) allows to override the default expected exit status. +* **COLOR** (optional) allows to use colors in the test (default `0`) +* **UTF8** (optional) allows to use utf-8 in the test (default `0`) * **EXPECT** is the expected output of the test from stdout. If `REGEXP_FILTER_OUT` is used, `EXPECT` matches only the filtered output. * **EXPECT_ERR** (optional) is the expected output of the test from stderr. Can be specified in addition or instead of `EXPECT` * **BROKEN** (optional) is 1 if the tests is expected to be fail, 0 or unspecified otherwise diff --git a/test/db/analysis/tricore b/test/db/analysis/tricore index 6c08958f41..5ec9803cbd 100644 --- a/test/db/analysis/tricore +++ b/test/db/analysis/tricore @@ -1,22 +1,22 @@ NAME=TriCore lea -FILE=malloc://512 -CMDS=!rz-asm -a tricore -d d916606c +TOOL=rz-asm +ARGS=-a tricore -d d916606c EXPECT=< [0x000006a0]>  [0x000006a0]>  [0x000006a0]> [0x000006a0]>   [0x000006a0]> e [0x000006a0]> e  [0x000006a0]> e [0x000006a0]> e   [0x000006a0]> e s [0x000006a0]> e s  [0x000006a0]> e sc [0x000006a0]> e sc  [0x000006a0]> e scr [0x000006a0]> e scr  [0x000006a0]> e scr. [0x000006a0]> e scr.  [0x000006a0]> e scr.p [0x000006a0]> e scr.p  [0x000006a0]> e scr.pr [0x000006a0]> e scr.pr  [0x000006a0]> e scr.pro [0x000006a0]> e scr.pro  [0x000006a0]> e scr.prom [0x000006a0]> e scr.prom  [0x000006a0]> e scr.promp [0x000006a0]> e scr.promp  [0x000006a0]> e scr.prompt [0x000006a0]> e scr.prompt  [0x000006a0]> e scr.prompt. [0x000006a0]> e scr.prompt.  [0x000006a0]> e scr.prompt.f [0x000006a0]> e scr.prompt.f  [0x000006a0]> e scr.prompt.fi [0x000006a0]> e scr.prompt.fi  [0x000006a0]> e scr.prompt.fil [0x000006a0]> e scr.prompt.fil  [0x000006a0]> e scr.prompt.file [0x000006a0]> e scr.prompt.file  [0x000006a0]> e scr.prompt.file= [0x000006a0]> e scr.prompt.file=  [0x000006a0]> e scr.prompt.file=t [0x000006a0]> e scr.prompt.file=t  [0x000006a0]> e scr.prompt.file=tr [0x000006a0]> e scr.prompt.file=tr  [0x000006a0]> e scr.prompt.file=tru [0x000006a0]> e scr.prompt.file=tru  [0x000006a0]> e scr.prompt.file=true [0x000006a0]> e scr.prompt.file=true [0x000006a0]> e scr.prompt.file=true @@ -240,15 +226,9 @@ EXPECT=< -h -FILE=-- -CMDS=< hex ; rz-ax 10 @@ -387,7 +379,14 @@ If expr is not provided, reads from stdin -w signed word ; rz-ax -w 16 0xffff -v version ; rz-ax -v -p position of set bits ; rz-ax -p 0xb3 +EOF +RUN +NAME=rz-bin -h +TOOL=rz-bin +ARGS=-h +EXIT_STATUS=1 +EXPECT=< - -a arch  Specify architecture plugin to use (x86, arm, ..) - -b bits  Specify register size for arch (16 (thumb), 32, 64, ..) - -d algo  Compute edit distance based on the chosen algorithm: -   myers | Eugene W. Myers' O(ND) algorithm (no substitution) -   leven | Levenshtein O(N^2) algorithm (with substitution) -   ssdeep | Context triggered piecewise hashing comparison - -i Use command line arguments instead of files (only for -d) - -H Hexadecimal visual mode - -h Show this help - -j JSON output - -q Quiet output - -V Show version information - -v Be more verbose (stderr output) - -K theme Set a give color theme (see rizin 'eco' command) - -e k=v  Set an evaluable config variable - -A Compare virtual and physical addresses - -B Run 'aaa' when loading the bin - -C Disable colors - -T Show timestamp information - -S WxH  Set the width and height of the terminal for visual mode - -0 cmd  Input for file0 when option -t 'commands' is given. -  The same value will be set for file1, if -1 is not set. - -1 cmd  Input for file1 when option -t 'commands' is given. - -t type  Compute the difference between two files based on its type: -   bytes | compare raw bytes in the files (only for small files) -   lines | compare text files -   functions | compare functions found in the files -   | optional -0 to compare only one function -   classes | compare classes found in the files -   command | compare command output returned when executed in both files -   | require -0 and -1 is optional -   entries | compare entries found in the files -   fields | compare fields found in the files -   graphs | compare 2 functions and outputs in graphviz/dot format -   | require -0 and -1 is optional -   imports | compare imports found in the files -   libraries | compare libraries found in the files -   sections | compare sections found in the files -   strings | compare strings found in the files -   symbols | compare symbols found in the files -palette colors can be changed by adding the following lines -inside the $HOME/.rizinrc file -ec diff.unknown blue | offset color -ec diff.match green | match color -ec diff.unmatch red | mismatch color + -a arch  Specify architecture plugin to use (x86, arm, ..) + -b bits  Specify register size for arch (16 (thumb), 32, 64, ..) + -d myers  Compute edit distance using Eugene W. Myers' O(ND) algorithm (no substitution) + -d leven  Compute edit distance using Levenshtein O(N^2) algorithm (with substitution) + -d ssdeep  Compute edit distance using Context triggered piecewise hashing comparison + -i Use command line arguments instead of files (only for -d) + -H Hexadecimal visual mode + -h Show this help + -j JSON output + -q Quiet output + -v Show version information + -V Be more verbose (stderr output) + -K theme  Set a give color theme (see rizin 'eco' command) + -e k=v  Set an evaluable config variable + -A Compare virtual and physical addresses + -B Run 'aaa' when loading the bin + -C Disable colors + -T Show timestamp information + -S WxH  Set the width and height of the terminal for visual mode + -0 cmd  Input for file0 when option -t 'commands' is given. +  The same value will be set for file1, if -1 is not set. + -1 cmd  Input for file1 when option -t 'commands' is given. + -t bytes  Compare raw bytes in the files (only for small files) + -t lines  Compare text files + -t functions Compare functions found in the files +  optional -0 to compare only one function + -t classes  Compare classes found in the files + -t command  Compare command output returned when executed in both files +  requires -0 and -1 is optional + -t entries  Compare entries found in the files + -t fields  Compare fields found in the files + -t graphs  Compare 2 functions and outputs in graphviz/dot format +  requires -0 and -1 is optional + -t imports  Compare imports found in the files + -t libraries Compare libraries found in the files + -t sections  Compare sections found in the files + -t strings  Compare strings found in the files + -t symbols  Compare symbols found in the files +Palette colors can be changed by adding the following lines inside the $HOME/.rizinrc file + ec diff.unknown blue | offset color + ec diff.match green | match color + ec diff.unmatch red | mismatch color +Environment variables + RZ_COLOR | enables/disables colors support +EOF +RUN +NAME=rz-find -h +TOOL=rz-find +ARGS=-h +EXPECT=< 11 len). +tricore Generic TriCore CPU family by Infineon EOF RUN diff --git a/test/db/tools/rz_ax b/test/db/tools/rz_ax index 5da31f2a5f..a703cf9e9f 100644 --- a/test/db/tools/rz_ax +++ b/test/db/tools/rz_ax @@ -1,30 +1,30 @@ NAME=rz-ax -I 3530468537 -FILE== -CMDS=!rz-ax -I 3530468537 +TOOL=rz-ax +ARGS=-I 3530468537 EXPECT=< 176 126 7E ~ +077 63 3F ? 177 127 7F DEL EOF RUN NAME=rz-ax -w 16 0xffff -FILE== -CMDS=!rz-ax -w 16 0xffff +TOOL=rz-ax +ARGS=-w 16 0xffff EXPECT=< 0 +NAME=baddr (2) FILE=bins/elf/analysis/hello-linux-x86_64 -CMDS=!rz-bin -qe ${RZ_FILE};!rz-bin -B 0x800000 -qe ${RZ_FILE} +TOOL=rz-bin +ARGS=-B 0x400000 -qe EXPECT=<size == sizeof(W32_EH_SHARED) +0x00001058 0x00403058 202 203 .rdata ascii /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_cross_i386-mingw32-gcc/i386-mingw32-gcc/work/gcc-3.4.5-20060117-2/gcc/config/i386/w32-shared-ptr.c +0x00001124 0x00403124 38 39 .rdata ascii GetAtomNameA (atom, s, sizeof(s)) != 0 +0x000012fe 0x004050fe 8 9 .idata ascii AddAtomA +0x0000130a 0x0040510a 11 12 .idata ascii ExitProcess +0x00001318 0x00405118 9 10 .idata ascii FindAtomA +0x00001324 0x00405124 12 13 .idata ascii GetAtomNameA +0x00001334 0x00405134 27 28 .idata ascii SetUnhandledExceptionFilter +0x00001352 0x00405152 13 14 .idata ascii __getmainargs +0x00001362 0x00405162 12 13 .idata ascii __p__environ +0x00001372 0x00405172 10 11 .idata ascii __p__fmode +0x00001380 0x00405180 14 15 .idata ascii __set_app_type +0x00001392 0x00405192 7 8 .idata ascii _assert +0x0000139c 0x0040519c 6 7 .idata ascii _cexit +0x000013a6 0x004051a6 4 5 .idata ascii _iob +0x000013ae 0x004051ae 7 8 .idata ascii _onexit +0x000013b8 0x004051b8 8 9 .idata ascii _setmode +0x000013c4 0x004051c4 5 6 .idata ascii abort +0x000013cc 0x004051cc 6 7 .idata ascii atexit +0x000013d6 0x004051d6 4 5 .idata ascii free +0x000013de 0x004051de 6 7 .idata ascii malloc +0x000013e8 0x004051e8 6 7 .idata ascii printf +0x000013f2 0x004051f2 6 7 .idata ascii signal +0x000013fd 0x004051fd 4 16 .idata utf32le PPPP +0x00001410 0x00405210 12 13 .idata ascii KERNEL32.dll +0x0000145c 0x0040525c 10 11 .idata ascii msvcrt.dll + EOF RUN NAME=rz-bin -zz pe FILE=bins/pe/ioli/w32/crackme0x00.exe -CMDS=!rz-bin -zz ${RZ_FILE} | grep "Password:" +TOOL=rz-bin +ARGS=-zz +REGEXP_FILTER_OUT=.+Password:.+ EXPECT=<>::bar EOF RUN NAME=rz-bin -D java -FILE== -CMDS=!rz-bin -D java "Fake([BCDFIJSZ)Ltest/class/name;" +FILE=Fake([BCDFIJSZ)Ltest/class/name; +TOOL=rz-bin +ARGS=-D java EXPECT=<.attr\n"},{"op":"equal","value":"align: 0x00000000 -r-x class.methods..attr.0.code\n"},{"op":"equal","value":"align: 0x00000000 -r-- class.methods.main.attr\n"},{"op":"equal","value":"align: 0x00000000 -r-x class.methods.main.attr.0.code\n"},{"op":"insert","value":"align: 0x00000000 -r-- class.methods.say.attr\n"},{"op":"insert","value":"align: 0x00000000 -r-x class.methods.say.attr.0.code\n"}]}]} EOF RUN NAME=rz-diff sections comparison with addresses -FILE== -CMDS=!rz-diff -C -At sections bins/java/Main.java.11.class bins/java/Hello.class +TOOL=rz-diff +ARGS=-At sections bins/java/Main.java.11.class bins/java/Hello.class EXPECT=<.attr\n"},{"op":"delete","value":"virt: 0x00000000000004a4:0x001d phys: 0x00000000000004a4:0x001d align: 0x00000000 -r-x class.methods..attr.0.code\n"},{"op":"delete","value":"virt: 0x00000000000004b9:0x00d1 phys: 0x00000000000004b9:0x00d1 align: 0x00000000 -r-- class.methods.main.attr\n"},{"op":"delete","value":"virt: 0x00000000000004cf:0x00c1 phys: 0x00000000000004cf:0x00c1 align: 0x00000000 -r-x class.methods.main.attr.0.code\n"},{"op":"insert","value":"virt: 0x00000000000002cd:0x0008 phys: 0x00000000000002cd:0x0008 align: 0x00000000 -r-- class.attr\n"},{"op":"insert","value":"virt: 0x000000000000000a:0x01ff phys: 0x000000000000000a:0x01ff align: 0x00000000 -r-- class.constant_pool\n"},{"op":"insert","value":"virt: 0x000000000000020b:0x000a phys: 0x000000000000020b:0x000a align: 0x00000000 -r-- class.fields\n"},{"op":"insert","value":"virt: 0x000000000000020b:0x000a phys: 0x000000000000020b:0x000a align: 0x00000000 -r-- class.fields.who.attr\n"},{"op":"insert","value":"virt: 0x0000000000000215:0x00b8 phys: 0x0000000000000215:0x00b8 align: 0x00000000 -r-- class.methods\n"},{"op":"insert","value":"virt: 0x0000000000000215:0x0038 phys: 0x0000000000000215:0x0038 align: 0x00000000 -r-- class.methods..attr\n"},{"op":"insert","value":"virt: 0x000000000000022b:0x002a phys: 0x000000000000022b:0x002a align: 0x00000000 -r-x class.methods..attr.0.code\n"},{"op":"insert","value":"virt: 0x0000000000000294:0x0039 phys: 0x0000000000000294:0x0039 align: 0x00000000 -r-- class.methods.main.attr\n"},{"op":"insert","value":"virt: 0x00000000000002aa:0x0029 phys: 0x00000000000002aa:0x0029 align: 0x00000000 -r-x class.methods.main.attr.0.code\n"},{"op":"insert","value":"virt: 0x000000000000024d:0x0047 phys: 0x000000000000024d:0x0047 align: 0x00000000 -r-- class.methods.say.attr\n"},{"op":"insert","value":"virt: 0x0000000000000263:0x0039 phys: 0x0000000000000263:0x0039 align: 0x00000000 -r-x class.methods.say.attr.0.code\n"}]}]} EOF @@ -641,8 +608,8 @@ RUN NAME=rz-diff symbols comparison -FILE== -CMDS=!rz-diff -C -t symbols bins/java/Main.java.11.class bins/java/Main.java.1.7.class +TOOL=rz-diff +ARGS=-t symbols bins/java/Main.java.11.class bins/java/Main.java.1.7.class EXPECT=<\n"},{"op":"equal","value":"Main Main Main.main\n"},{"op":"equal","value":"java.lang.Object Object Object.\n"},{"op":"insert","value":"java.lang.StringBuilder StringBuilder StringBuilder.\n"},{"op":"insert","value":"java.lang.StringBuilder StringBuilder StringBuilder.append\n"},{"op":"insert","value":"java.lang.StringBuilder StringBuilder StringBuilder.toString\n"},{"op":"equal","value":"java.lang.System System System.err\n"},{"op":"equal","value":"java.lang.System System System.out\n"},{"op":"equal","value":"java.io.BufferedReader java.io.BufferedReader java.io.BufferedReader.\n"}]},{"from":[10,4],"to":[13,3],"ops":[{"op":"equal","value":"java.io.FileReader java.io.FileReader java.io.FileReader.\n"},{"op":"equal","value":"java.io.PrintStream java.io.PrintStream java.io.PrintStream.format\n"},{"op":"equal","value":"java.io.PrintStream java.io.PrintStream java.io.PrintStream.println\n"},{"op":"delete","value":"java.lang.invoke.StringConcatFactory java.lang.invoke.StringConcatFactory java.lang.invoke.StringConcatFactory.makeConcatWithConstants\n"}]}]} EOF RUN NAME=rz-diff symbols comparison with addresses -FILE== -CMDS=!rz-diff -C -At symbols bins/java/Main.java.11.class bins/java/Main.java.1.7.class +TOOL=rz-diff +ARGS=-At symbols bins/java/Main.java.11.class bins/java/Main.java.1.7.class EXPECT=<\n"},{"op":"delete","value":"virt: 0x00000000000004cf phys: 0x00000000000004cf Main Main Main.main\n"},{"op":"insert","value":"virt: 0x00000000000002aa phys: 0x00000000000002aa java.lang.Exception Exception Exception.printStackTrace\n"},{"op":"insert","value":"virt: 0x0000000000000383 phys: 0x0000000000000383 Main Main Main.\n"},{"op":"insert","value":"virt: 0x00000000000003ae phys: 0x00000000000003ae Main Main Main.main\n"},{"op":"equal","value":"virt: 0x000000000000000a phys: 0x000000000000000a java.lang.Object Object Object.\n"},{"op":"delete","value":"virt: 0x00000000000001e2 phys: 0x00000000000001e2 java.lang.System System System.err\n"},{"op":"insert","value":"virt: 0x0000000000000187 phys: 0x0000000000000187 java.lang.StringBuilder StringBuilder StringBuilder.\n"},{"op":"insert","value":"virt: 0x0000000000000198 phys: 0x0000000000000198 java.lang.StringBuilder StringBuilder StringBuilder.append\n"},{"op":"insert","value":"virt: 0x00000000000001db phys: 0x00000000000001db java.lang.StringBuilder StringBuilder StringBuilder.toString\n"},{"op":"insert","value":"virt: 0x000000000000021b phys: 0x000000000000021b java.lang.System System System.err\n"},{"op":"equal","value":"virt: 0x0000000000000039 phys: 0x0000000000000039 java.lang.System System System.out\n"},{"op":"equal","value":"virt: 0x000000000000011e phys: 0x000000000000011e java.io.BufferedReader java.io.BufferedReader java.io.BufferedReader.\n"},{"op":"delete","value":"virt: 0x00000000000001b7 phys: 0x00000000000001b7 java.io.BufferedReader java.io.BufferedReader java.io.BufferedReader.close\n"},{"op":"insert","value":"virt: 0x00000000000001f0 phys: 0x00000000000001f0 java.io.BufferedReader java.io.BufferedReader java.io.BufferedReader.close\n"},{"op":"equal","value":"virt: 0x000000000000013e phys: 0x000000000000013e java.io.BufferedReader java.io.BufferedReader java.io.BufferedReader.readLine\n"},{"op":"equal","value":"virt: 0x0000000000000114 phys: 0x0000000000000114 java.io.FileReader java.io.FileReader java.io.FileReader.\n"},{"op":"delete","value":"virt: 0x000000000000021f phys: 0x000000000000021f java.io.PrintStream java.io.PrintStream java.io.PrintStream.format\n"},{"op":"insert","value":"virt: 0x0000000000000258 phys: 0x0000000000000258 java.io.PrintStream java.io.PrintStream java.io.PrintStream.format\n"},{"op":"equal","value":"virt: 0x0000000000000088 phys: 0x0000000000000088 java.io.PrintStream java.io.PrintStream java.io.PrintStream.println\n"},{"op":"delete","value":"virt: 0x000000000000033f phys: 0x000000000000033f java.lang.invoke.StringConcatFactory java.lang.invoke.StringConcatFactory java.lang.invoke.StringConcatFactory.makeConcatWithConstants\n"}]}]} EOF @@ -716,16 +683,17 @@ RUN NAME=rz-diff command with zero argument -FILE== -CMDS=!rz-diff -C -t command bins/java/Main.java.11.class bins/java/Hello.class +TOOL=rz-diff +ARGS=-t command bins/java/Main.java.11.class bins/java/Hello.class +EXIT_STATUS=1 EXPECT_ERR=<. EOF RUN NAME=rz-diff command with one argument -FILE== -CMDS=!rz-diff -C -0 javac -t command bins/java/Main.java.11.class bins/java/Main.java.15.class +TOOL=rz-diff +ARGS=-0 javac -t command bins/java/Main.java.11.class bins/java/Main.java.15.class EXPECT=<= U+10000 -FILE== -CMDS=!rz-find -w 𐍈 bins/elf/strenc +TOOL=rz-find +ARGS=-w 𐍈 bins/elf/strenc EXPECT=< /dev/null -EXPECT= -RUN - #CLANG=e900000000488d3524000000bf01000000b80400000248c7c2070000000f05b80100000248c7c7000000000f0531c0c348656c6c6f210a00 NAME=rz-ggc bins/other/rz-gg/hi.c BROKEN=1 -FILE== -CMDS=!rz-gg bins/other/rz-gg/hi.c | grep e9 +TOOL=rz-gg +ARGS=bins/other/rz-gg/hi.c +REGEXP_FILTER_OUT=e9.+ EXPECT=<@ in `@32@` @@ -24,8 +9,9 @@ EOF RUN NAME=rz-run repeat error -FILE== -CMDS=!rz-run arg1='@32aaa' -- echo +TOOL=rz-run +ARGS=arg1=@32aaa -- echo +EXIT_STATUS=1 REGEXP_FILTER_ERR=(ERROR: rz-run:.+$) EXPECT_ERR=<@ in `@32aaa` diff --git a/test/db/tools/rz_sign b/test/db/tools/rz_sign index 3647a3dd14..2f26a63e39 100644 --- a/test/db/tools/rz_sign +++ b/test/db/tools/rz_sign @@ -1,22 +1,6 @@ -NAME=rz-sign version -FILE== -CMDS=!!rz-sign -v~? -EXPECT=<