From e5797fa7170209b91e51f0958b1a5770e5648f6d Mon Sep 17 00:00:00 2001 From: Anton Kochkov Date: Mon, 14 Feb 2022 22:35:27 +0800 Subject: [PATCH] Conver `as` commands to the rzshell --- librz/core/cmd/cmd_analysis.c | 324 ++++++++----------------- librz/core/cmd_descs/cmd_analysis.yaml | 40 +++ librz/core/cmd_descs/cmd_descs.c | 88 +++++++ librz/core/cmd_descs/cmd_descs.h | 5 + librz/core/csyscall.c | 96 ++++++++ librz/core/disasm.c | 2 +- librz/core/meson.build | 1 + librz/include/rz_core.h | 3 +- test/db/json/json2 | 2 +- 9 files changed, 328 insertions(+), 233 deletions(-) create mode 100644 librz/core/csyscall.c diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index 8bd925d71c6..a9f484f0007 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -395,19 +395,6 @@ static const char *help_msg_ao[] = { NULL }; -static const char *help_msg_as[] = { - "Usage: as[ljk?]", "", "syscall name <-> number utility", - "as", "", "show current syscall and arguments", - "as", " 4", "show syscall 4 based on asm.os and current regs/mem", - "asc[a]", " 4", "dump syscall info in .asm or .h", - "asj", "", "list of syscalls in JSON", - "asl", "", "list of syscalls by asm.os and asm.arch", - "asl", " close", "returns the syscall number for close", - "asl", " 4", "returns the name of the syscall number 4", - "ask", " [query]", "perform syscall/ queries", - NULL -}; - /** * \brief Helper to get function in \p offset * @@ -711,86 +698,6 @@ static void cmd_analysis_trampoline(RzCore *core, const char *input) { } } -static const char *syscallNumber(int n) { - return sdb_fmt(n > 1000 ? "0x%x" : "%d", n); -} - -RZ_API char *cmd_syscall_dostr(RzCore *core, st64 n, ut64 addr) { - int i; - char str[64]; - st64 N = n; - int defVector = rz_syscall_get_swi(core->analysis->syscall); - if (defVector > 0) { - n = -1; - } - if (n == -1 || defVector > 0) { - n = (int)rz_core_reg_getv_by_role_or_name(core, "oeax"); - if (!n || n == -1) { - const char *a0 = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SN); - n = (a0 == NULL) ? -1 : (int)rz_core_reg_getv_by_role_or_name(core, a0); - } - } - RzSyscallItem *item = rz_syscall_get(core->analysis->syscall, n, defVector); - if (!item) { - item = rz_syscall_get(core->analysis->syscall, N, -1); - } - if (!item) { - return rz_str_newf("%s = unknown ()", syscallNumber(n)); - } - char *res = rz_str_newf("%s = %s (", syscallNumber(item->num), item->name); - // TODO: move this to rz_syscall - const char *cc = rz_analysis_syscc_default(core->analysis); - // TODO replace the hardcoded CC with the sdb ones - for (i = 0; i < item->args; i++) { - // XXX this is a hack to make syscall args work on x86-32 and x86-64 - // we need to shift sn first.. which is bad, but needs to be redesigned - int regidx = i; - if (core->rasm->bits == 32 && core->rasm->cur && !strcmp(core->rasm->cur->arch, "x86")) { - regidx++; - } - ut64 arg = rz_core_arg_get(core, cc, regidx); // TODO here - // rz_cons_printf ("(%d:0x%"PFMT64x")\n", i, arg); - if (item->sargs) { - switch (item->sargs[i]) { - case 'p': // pointer - res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); - break; - case 'i': - res = rz_str_appendf(res, "%" PFMT64u "", arg); - break; - case 'z': - memset(str, 0, sizeof(str)); - rz_io_read_at(core->io, arg, (ut8 *)str, sizeof(str) - 1); - rz_str_filter(str, strlen(str)); - res = rz_str_appendf(res, "\"%s\"", str); - break; - case 'Z': { - // TODO replace the hardcoded CC with the sdb ones - ut64 len = rz_core_arg_get(core, cc, i + 2); - len = RZ_MIN(len + 1, sizeof(str) - 1); - if (len == 0) { - len = 16; // override default - } - (void)rz_io_read_at(core->io, arg, (ut8 *)str, len); - str[len] = 0; - rz_str_filter(str, -1); - res = rz_str_appendf(res, "\"%s\"", str); - } break; - default: - res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); - break; - } - } else { - res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); - } - if (i + 1 < item->args) { - res = rz_str_appendf(res, ", "); - } - } - rz_syscall_item_free(item); - return rz_str_appendf(res, ")"); -} - static int mw(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len) { int *ec = (int *)esil->user; *ec += (len * 2); @@ -818,14 +725,6 @@ static int esil_cost(RzCore *core, ut64 addr, const char *expr) { return ec; } -static void cmd_syscall_do(RzCore *core, st64 n, ut64 addr) { - char *msg = cmd_syscall_dostr(core, n, addr); - if (msg) { - rz_cons_println(msg); - free(msg); - } -} - #define printline(k, fmt, arg) \ { \ if (use_color) \ @@ -3930,143 +3829,113 @@ RZ_API void rz_cmd_analysis_calls(RzCore *core, const char *input, bool printCom rz_list_free(ranges); } -static void cmd_sdbk(Sdb *db, const char *input) { - char *out = (input[0] == ' ') - ? sdb_querys(db, NULL, 0, input + 1) - : sdb_querys(db, NULL, 0, "*"); - if (out) { - rz_cons_println(out); - free(out); - } else { - eprintf("|ERROR| Usage: ask [query]\n"); +RZ_IPI RzCmdStatus rz_analysis_syscall_show_handler(RzCore *core, int argc, const char **argv) { + st64 n = argc > 1 ? rz_num_math(core->num, argv[1]) : -1; + char *sysc = rz_core_syscall_as_string(core, n, core->offset); + if (!sysc) { + RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", n); + return RZ_CMD_STATUS_ERROR; } + rz_cons_println(sysc); + free(sysc); + return RZ_CMD_STATUS_OK; } -static void cmd_analysis_syscall(RzCore *core, const char *input) { - PJ *pj = NULL; - RzSyscallItem *si; +static const char *syscallNumber(int n) { + return sdb_fmt(n > 1000 ? "0x%x" : "%d", n); +} + +RZ_IPI RzCmdStatus rz_analysis_syscall_print_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { RzListIter *iter; - RzList *list; - RzNum *num = NULL; - int n; + RzSyscallItem *si; + RzList *list = rz_syscall_list(core->analysis->syscall); + rz_cmd_state_output_array_start(state); + rz_list_foreach (list, iter, si) { + switch (state->mode) { + case RZ_OUTPUT_MODE_STANDARD: + rz_cons_printf("%s = 0x%02x.%s\n", + si->name, si->swi, syscallNumber(si->num)); + break; + case RZ_OUTPUT_MODE_JSON: + pj_o(state->d.pj); + pj_ks(state->d.pj, "name", si->name); + pj_ki(state->d.pj, "swi", si->swi); + pj_ki(state->d.pj, "num", si->num); + pj_end(state->d.pj); + break; + default: + rz_warn_if_reached(); + break; + } + } + rz_cmd_state_output_array_end(state); + rz_list_free(list); + return RZ_CMD_STATUS_OK; +} - switch (input[0]) { - case 'c': // "asc" - if (input[1] == 'a') { - if (input[2] == ' ') { - if (!isalpha((ut8)input[3]) && (n = rz_num_math(num, input + 3)) >= 0) { - si = rz_syscall_get(core->analysis->syscall, n, -1); - if (si) { - rz_cons_printf(".equ SYS_%s %s\n", si->name, syscallNumber(n)); - rz_syscall_item_free(si); - } else - eprintf("Unknown syscall number\n"); - } else { - n = rz_syscall_get_num(core->analysis->syscall, input + 3); - if (n != -1) { - rz_cons_printf(".equ SYS_%s %s\n", input + 3, syscallNumber(n)); - } else { - eprintf("Unknown syscall name\n"); - } - } - } else { - list = rz_syscall_list(core->analysis->syscall); - rz_list_foreach (list, iter, si) { - rz_cons_printf(".equ SYS_%s %s\n", - si->name, syscallNumber(si->num)); - } - rz_list_free(list); - } - } else { - if (input[1] == ' ') { - if (!isalpha((ut8)input[2]) && (n = rz_num_math(num, input + 2)) >= 0) { - si = rz_syscall_get(core->analysis->syscall, n, -1); - if (si) { - rz_cons_printf("#define SYS_%s %s\n", si->name, syscallNumber(n)); - rz_syscall_item_free(si); - } else - eprintf("Unknown syscall number\n"); - } else { - n = rz_syscall_get_num(core->analysis->syscall, input + 2); - if (n != -1) { - rz_cons_printf("#define SYS_%s %s\n", input + 2, syscallNumber(n)); - } else { - eprintf("Unknown syscall name\n"); - } - } - } else { - list = rz_syscall_list(core->analysis->syscall); - rz_list_foreach (list, iter, si) { - rz_cons_printf("#define SYS_%s %s\n", - si->name, syscallNumber(si->num)); - } - rz_list_free(list); +RZ_IPI RzCmdStatus rz_analysis_syscall_name_handler(RzCore *core, int argc, const char **argv) { + st64 num = rz_syscall_get_num(core->analysis->syscall, argv[1]); + if (num < 1) { + RZ_LOG_ERROR("Cannot resolve syscall: %s\n", argv[1]); + return RZ_CMD_STATUS_ERROR; + } + char *sysc = rz_core_syscall_as_string(core, num, core->offset); + if (!sysc) { + RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", num); + return RZ_CMD_STATUS_ERROR; + } + rz_cons_println(sysc); + free(sysc); + return RZ_CMD_STATUS_OK; +} + +static RzCmdStatus syscall_dump(RzCore *core, int argc, const char **argv, bool is_c) { + if (argc > 1) { + st64 n = rz_num_math(core->num, argv[1]); + if (n < 1) { + n = rz_syscall_get_num(core->analysis->syscall, argv[1]); + if (n == -1) { + RZ_LOG_ERROR("Cannot resolve syscall: %s\n", argv[1]); + return RZ_CMD_STATUS_ERROR; } + rz_cons_printf(".equ SYS_%s %s\n", argv[1], syscallNumber(n)); + return RZ_CMD_STATUS_OK; } - break; - case 'k': // "ask" - cmd_sdbk(core->analysis->syscall->db, input + 1); - break; - case 'l': // "asl" - if (input[1] == ' ') { - if (!isalpha((ut8)input[2]) && (n = rz_num_math(num, input + 2)) >= 0) { - si = rz_syscall_get(core->analysis->syscall, n, -1); - if (si) { - rz_cons_println(si->name); - rz_syscall_item_free(si); - } else - eprintf("Unknown syscall number\n"); - } else { - n = rz_syscall_get_num(core->analysis->syscall, input + 2); - if (n != -1) { - rz_cons_printf("%s\n", syscallNumber(n)); - } else { - eprintf("Unknown syscall name\n"); - } - } + RzSyscallItem *si = rz_syscall_get(core->analysis->syscall, n, -1); + if (!si) { + RZ_LOG_ERROR("Cannot resolve syscall: %" PFMT64d "\n", n); + return RZ_CMD_STATUS_ERROR; + } + if (is_c) { + rz_cons_printf("#define SYS_%s %s\n", si->name, syscallNumber(n)); } else { - list = rz_syscall_list(core->analysis->syscall); - rz_list_foreach (list, iter, si) { - rz_cons_printf("%s = 0x%02x.%s\n", - si->name, si->swi, syscallNumber(si->num)); - } - rz_list_free(list); + rz_cons_printf(".equ SYS_%s %s\n", si->name, syscallNumber(n)); } - break; - case 'j': // "asj" - pj = pj_new(); - pj_a(pj); - list = rz_syscall_list(core->analysis->syscall); + rz_syscall_item_free(si); + } else { + RzListIter *iter; + RzSyscallItem *si; + RzList *list = rz_syscall_list(core->analysis->syscall); rz_list_foreach (list, iter, si) { - pj_o(pj); - pj_ks(pj, "name", si->name); - pj_ki(pj, "swi", si->swi); - pj_ki(pj, "num", si->num); - pj_end(pj); - } - pj_end(pj); - if (pj) { - rz_cons_println(pj_string(pj)); - pj_free(pj); - } - break; - case '\0': // "as" - cmd_syscall_do(core, -1, core->offset); - break; - case ' ': // "as " - { - const char *sn = rz_str_trim_head_ro(input + 1); - st64 num = rz_syscall_get_num(core->analysis->syscall, sn); - if (num < 1) { - num = (int)rz_num_get(core->num, sn); + if (is_c) { + rz_cons_printf("#define SYS_%s %s\n", + si->name, syscallNumber(si->num)); + } else { + rz_cons_printf(".equ SYS_%s %s\n", + si->name, syscallNumber(si->num)); + } } - cmd_syscall_do(core, num, -1); - } break; - default: - case '?': // "as?" - rz_core_cmd_help(core, help_msg_as); - break; + rz_list_free(list); } + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_analysis_syscall_dump_assembly_handler(RzCore *core, int argc, const char **argv) { + return syscall_dump(core, argc, argv, false); +} + +RZ_IPI RzCmdStatus rz_analysis_syscall_dump_c_handler(RzCore *core, int argc, const char **argv) { + return syscall_dump(core, argc, argv, true); } static void cmd_analysis_ucall_ref(RzCore *core, ut64 addr) { @@ -5837,9 +5706,6 @@ RZ_IPI int rz_cmd_analysis(void *data, const char *input) { case 'g': // "ag" cmd_analysis_graph(core, input + 1); break; - case 's': // "as" - cmd_analysis_syscall(core, input + 1); - break; case '*': // "a*" rz_core_cmd0_rzshell(core, "afl*"); rz_core_cmd0_rzshell(core, "ah*"); diff --git a/librz/core/cmd_descs/cmd_analysis.yaml b/librz/core/cmd_descs/cmd_analysis.yaml index 61258ac8e3f..4145c18cf6d 100644 --- a/librz/core/cmd_descs/cmd_analysis.yaml +++ b/librz/core/cmd_descs/cmd_analysis.yaml @@ -1453,3 +1453,43 @@ commands: - name: class_name type: RZ_CMD_ARG_TYPE_STRING optional: true + - name: as + summary: Syscalls + subcommands: + - name: as + summary: Show syscall and arguments + cname: analysis_syscall_show + args: + - name: syscall + type: RZ_CMD_ARG_TYPE_NUM + optional: true + - name: asl + summary: List syscalls + cname: analysis_syscall_print + type: RZ_CMD_DESC_TYPE_ARGV_STATE + default_mode: RZ_OUTPUT_MODE_STANDARD + modes: + - RZ_OUTPUT_MODE_STANDARD + - RZ_OUTPUT_MODE_JSON + args: [] + - name: asca + summary: Dump syscall info into .asm file + cname: analysis_syscall_dump_assembly + args: + - name: syscall + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: asc + summary: Dump syscall info into .h file + cname: analysis_syscall_dump_c + args: + - name: syscall + type: RZ_CMD_ARG_TYPE_STRING + optional: true + - name: asn + summary: Returns the syscall number by the name + cname: analysis_syscall_name + args: + - name: name + type: RZ_CMD_ARG_TYPE_STRING + diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index 7fa0484f9b1..87277b9bcfc 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -176,6 +176,10 @@ static const RzCmdDescArg analysis_class_vtable_add_args[5]; static const RzCmdDescArg analysis_class_vtable_del_args[3]; static const RzCmdDescArg analysis_class_vtable_list_args[2]; static const RzCmdDescArg analysis_class_vtable_lookup_args[3]; +static const RzCmdDescArg analysis_syscall_show_args[2]; +static const RzCmdDescArg analysis_syscall_dump_assembly_args[2]; +static const RzCmdDescArg analysis_syscall_dump_c_args[2]; +static const RzCmdDescArg analysis_syscall_name_args[2]; static const RzCmdDescArg block_args[2]; static const RzCmdDescArg block_decrease_args[2]; static const RzCmdDescArg block_increase_args[2]; @@ -3563,6 +3567,75 @@ static const RzCmdDescHelp analysis_class_vtable_lookup_help = { .args = analysis_class_vtable_lookup_args, }; +static const RzCmdDescHelp as_help = { + .summary = "Syscalls", +}; +static const RzCmdDescArg analysis_syscall_show_args[] = { + { + .name = "syscall", + .type = RZ_CMD_ARG_TYPE_NUM, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp analysis_syscall_show_help = { + .summary = "Show syscall and arguments", + .args = analysis_syscall_show_args, +}; + +static const RzCmdDescArg analysis_syscall_print_args[] = { + { 0 }, +}; +static const RzCmdDescHelp analysis_syscall_print_help = { + .summary = "List syscalls", + .args = analysis_syscall_print_args, +}; + +static const RzCmdDescArg analysis_syscall_dump_assembly_args[] = { + { + .name = "syscall", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp analysis_syscall_dump_assembly_help = { + .summary = "Dump syscall info into .asm file", + .args = analysis_syscall_dump_assembly_args, +}; + +static const RzCmdDescArg analysis_syscall_dump_c_args[] = { + { + .name = "syscall", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp analysis_syscall_dump_c_help = { + .summary = "Dump syscall info into .h file", + .args = analysis_syscall_dump_c_args, +}; + +static const RzCmdDescArg analysis_syscall_name_args[] = { + { + .name = "name", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp analysis_syscall_name_help = { + .summary = "Returns the syscall number by the name", + .args = analysis_syscall_name_args, +}; + static const RzCmdDescHelp b_help = { .summary = "Display or change the block size", }; @@ -12444,6 +12517,21 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *analysis_class_vtable_lookup_cd = rz_cmd_desc_argv_new(core->rcmd, acv_cd, "acvf", rz_analysis_class_vtable_lookup_handler, &analysis_class_vtable_lookup_help); rz_warn_if_fail(analysis_class_vtable_lookup_cd); + RzCmdDesc *as_cd = rz_cmd_desc_group_new(core->rcmd, cmd_analysis_cd, "as", rz_analysis_syscall_show_handler, &analysis_syscall_show_help, &as_help); + rz_warn_if_fail(as_cd); + RzCmdDesc *analysis_syscall_print_cd = rz_cmd_desc_argv_state_new(core->rcmd, as_cd, "asl", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_analysis_syscall_print_handler, &analysis_syscall_print_help); + rz_warn_if_fail(analysis_syscall_print_cd); + rz_cmd_desc_set_default_mode(analysis_syscall_print_cd, RZ_OUTPUT_MODE_STANDARD); + + RzCmdDesc *analysis_syscall_dump_assembly_cd = rz_cmd_desc_argv_new(core->rcmd, as_cd, "asca", rz_analysis_syscall_dump_assembly_handler, &analysis_syscall_dump_assembly_help); + rz_warn_if_fail(analysis_syscall_dump_assembly_cd); + + RzCmdDesc *analysis_syscall_dump_c_cd = rz_cmd_desc_argv_new(core->rcmd, as_cd, "asc", rz_analysis_syscall_dump_c_handler, &analysis_syscall_dump_c_help); + rz_warn_if_fail(analysis_syscall_dump_c_cd); + + RzCmdDesc *analysis_syscall_name_cd = rz_cmd_desc_argv_new(core->rcmd, as_cd, "asn", rz_analysis_syscall_name_handler, &analysis_syscall_name_help); + rz_warn_if_fail(analysis_syscall_name_cd); + RzCmdDesc *b_cd = rz_cmd_desc_group_state_new(core->rcmd, root_cd, "b", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_RIZIN, rz_block_handler, &block_help, &b_help); rz_warn_if_fail(b_cd); RzCmdDesc *block_decrease_cd = rz_cmd_desc_argv_new(core->rcmd, b_cd, "b-", rz_block_decrease_handler, &block_decrease_help); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index 7d8a39a5725..e6d31e50878 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -219,6 +219,11 @@ RZ_IPI RzCmdStatus rz_analysis_class_vtable_add_handler(RzCore *core, int argc, RZ_IPI RzCmdStatus rz_analysis_class_vtable_del_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_analysis_class_vtable_list_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_analysis_class_vtable_lookup_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_analysis_syscall_show_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_analysis_syscall_print_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +RZ_IPI RzCmdStatus rz_analysis_syscall_dump_assembly_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_analysis_syscall_dump_c_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_analysis_syscall_name_handler(RzCore *core, int argc, const char **argv); RZ_IPI int rz_cmd_analysis(void *data, const char *input); RZ_IPI RzCmdStatus rz_block_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); RZ_IPI RzCmdStatus rz_block_decrease_handler(RzCore *core, int argc, const char **argv); diff --git a/librz/core/csyscall.c b/librz/core/csyscall.c new file mode 100644 index 00000000000..490334c02ba --- /dev/null +++ b/librz/core/csyscall.c @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: 2009-2021 pancake +// SPDX-FileCopyrightText: 2009-2021 maijin +// SPDX-License-Identifier: LGPL-3.0-only + +#include + +static const char *syscallNumber(int n) { + return sdb_fmt(n > 1000 ? "0x%x" : "%d", n); +} + +/** + * \brief Returns the syscall representation as a string + * + * Given the syscall number and address it resolves the syscall + * for the selected `asm.arch` and `asm.os` values and print + * its arguments. + * + * \param core RzCore instance + * \param n number of the syscall + * \param addr address of the syscall + */ +RZ_API RZ_OWN char *rz_core_syscall_as_string(RzCore *core, st64 n, ut64 addr) { + int i; + char str[64]; + st64 N = n; + int defVector = rz_syscall_get_swi(core->analysis->syscall); + if (defVector > 0) { + n = -1; + } + if (n == -1 || defVector > 0) { + n = (int)rz_core_reg_getv_by_role_or_name(core, "oeax"); + if (!n || n == -1) { + const char *a0 = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SN); + n = (a0 == NULL) ? -1 : (int)rz_core_reg_getv_by_role_or_name(core, a0); + } + } + RzSyscallItem *item = rz_syscall_get(core->analysis->syscall, n, defVector); + if (!item) { + item = rz_syscall_get(core->analysis->syscall, N, -1); + } + if (!item) { + return rz_str_newf("%s = unknown ()", syscallNumber(n)); + } + char *res = rz_str_newf("%s = %s (", syscallNumber(item->num), item->name); + // TODO: move this to rz_syscall + const char *cc = rz_analysis_syscc_default(core->analysis); + // TODO replace the hardcoded CC with the sdb ones + for (i = 0; i < item->args; i++) { + // XXX this is a hack to make syscall args work on x86-32 and x86-64 + // we need to shift sn first.. which is bad, but needs to be redesigned + int regidx = i; + if (core->rasm->bits == 32 && core->rasm->cur && !strcmp(core->rasm->cur->arch, "x86")) { + regidx++; + } + ut64 arg = rz_core_arg_get(core, cc, regidx); // TODO here + // rz_cons_printf ("(%d:0x%"PFMT64x")\n", i, arg); + if (item->sargs) { + switch (item->sargs[i]) { + case 'p': // pointer + res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); + break; + case 'i': + res = rz_str_appendf(res, "%" PFMT64u "", arg); + break; + case 'z': + memset(str, 0, sizeof(str)); + rz_io_read_at(core->io, arg, (ut8 *)str, sizeof(str) - 1); + rz_str_filter(str, strlen(str)); + res = rz_str_appendf(res, "\"%s\"", str); + break; + case 'Z': { + // TODO replace the hardcoded CC with the sdb ones + ut64 len = rz_core_arg_get(core, cc, i + 2); + len = RZ_MIN(len + 1, sizeof(str) - 1); + if (len == 0) { + len = 16; // override default + } + (void)rz_io_read_at(core->io, arg, (ut8 *)str, len); + str[len] = 0; + rz_str_filter(str, -1); + res = rz_str_appendf(res, "\"%s\"", str); + } break; + default: + res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); + break; + } + } else { + res = rz_str_appendf(res, "0x%08" PFMT64x "", arg); + } + if (i + 1 < item->args) { + res = rz_str_appendf(res, ", "); + } + } + rz_syscall_item_free(item); + return rz_str_appendf(res, ")"); +} diff --git a/librz/core/disasm.c b/librz/core/disasm.c index b6f49350dfc..ac7bfbe1f6e 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -4742,7 +4742,7 @@ static void ds_print_esil_analysis(RzDisasmState *ds) { } switch (ds->analysis_op.type) { case RZ_ANALYSIS_OP_TYPE_SWI: { - char *s = cmd_syscall_dostr(core, ds->analysis_op.val, at); + char *s = rz_core_syscall_as_string(core, ds->analysis_op.val, at); if (s) { ds_comment_esil(ds, true, true, "; %s", s); free(s); diff --git a/librz/core/meson.build b/librz/core/meson.build index 944ad1e0a91..62dd2c06758 100644 --- a/librz/core/meson.build +++ b/librz/core/meson.build @@ -36,6 +36,7 @@ rz_core_sources = [ 'csign.c', 'ctypes.c', 'cvfile.c', + 'csyscall.c', 'disasm.c', 'fortune.c', 'gdiff.c', diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 1ca1072c3dd..2d380ec2563 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -1029,8 +1029,7 @@ RZ_API void rz_core_analysis_stats_free(RzCoreAnalStats *s); RZ_API int rz_line_hist_offset_up(RzLine *line); RZ_API int rz_line_hist_offset_down(RzLine *line); -// TODO : move into debug or syscall++ -RZ_API char *cmd_syscall_dostr(RzCore *core, st64 num, ut64 addr); +RZ_API RZ_OWN char *rz_core_syscall_as_string(RzCore *core, st64 num, ut64 addr); /* tasks */ diff --git a/test/db/json/json2 b/test/db/json/json2 index 365902fc3e5..36c9f89ed0a 100644 --- a/test/db/json/json2 +++ b/test/db/json/json2 @@ -1,7 +1,7 @@ aoj aomj arj -asj +aslj avj axfj axfj @ sym.main