diff --git a/librz/core/cmd/cmd_debug.c b/librz/core/cmd/cmd_debug.c index 1e2cfaa3a3e..17fd811a9bd 100644 --- a/librz/core/cmd/cmd_debug.c +++ b/librz/core/cmd/cmd_debug.c @@ -130,19 +130,6 @@ static const char *help_msg_dmi[] = { NULL }; -static const char *help_msg_dx[] = { - "Usage: dx", "", " # Code injection commands", - "dx", " ...", "Inject opcodes", - "dxa", " nop", "Assemble code and inject", - "dxe", " egg-expr", "Compile egg expression and inject it", - "dxr", " ...", "Inject opcodes and restore state", - "dxs", " write 1, 0x8048, 12", "Syscall injection (see gs)", - "\nExamples:", "", "", - "dx", " 9090", "Inject two x86 nop", - "\"dxa mov eax,6;mov ebx,0;int 0x80\"", "", "Inject and restore state", - NULL -}; - struct dot_trace_ght { RzGraph /**/ *graph; Sdb *graphnodes; @@ -2232,90 +2219,6 @@ RZ_IPI int rz_cmd_debug(void *data, const char *input) { } rz_cons_break_pop(); break; - case 'x': // "dx" - switch (input[1]) { - case ' ': { // "dx " - ut8 bytes[4096]; - if (strlen(input + 2) < 4096) { - int bytes_len = rz_hex_str2bin(input + 2, bytes); - if (bytes_len > 0) { - rz_debug_execute(core->dbg, - bytes, bytes_len, 0); - } else { - RZ_LOG_ERROR("core: Invalid hexpairs\n"); - } - } else { - RZ_LOG_ERROR("core: the opcodes to inject are too long (> 2048 bytes)\n"); - } - break; - } - case 'a': { // "dxa" - RzAsmCode *acode; - rz_asm_set_pc(core->rasm, core->offset); - acode = rz_asm_massemble(core->rasm, input + 2); - if (acode) { - rz_reg_arena_push(core->dbg->reg); - rz_debug_execute(core->dbg, acode->bytes, acode->len, 0); - rz_reg_arena_pop(core->dbg->reg); - } - rz_asm_code_free(acode); - break; - } - case 'e': { // "dxe" - RzEgg *egg = core->egg; - RzBuffer *b; - const char *asm_arch = rz_config_get(core->config, "asm.arch"); - int asm_bits = rz_config_get_i(core->config, "asm.bits"); - const char *asm_os = rz_config_get(core->config, "asm.os"); - rz_egg_setup(egg, asm_arch, asm_bits, 0, asm_os); - rz_egg_reset(egg); - rz_egg_load(egg, input + 1, 0); - rz_egg_compile(egg); - b = rz_egg_get_bin(egg); - rz_asm_set_pc(core->rasm, core->offset); - rz_reg_arena_push(core->dbg->reg); - ut64 tmpsz; - const ut8 *tmp = rz_buf_data(b, &tmpsz); - rz_debug_execute(core->dbg, tmp, tmpsz, 0); - rz_reg_arena_pop(core->dbg->reg); - break; - } - case 'r': // "dxr" - rz_reg_arena_push(core->dbg->reg); - if (input[2] == ' ') { - ut8 bytes[4096]; - if (strlen(input + 2) < 4096) { - int bytes_len = rz_hex_str2bin(input + 2, - bytes); - if (bytes_len > 0) { - rz_debug_execute(core->dbg, - bytes, bytes_len, - 0); - } else { - RZ_LOG_ERROR("core: Invalid hexpairs\n"); - } - } else { - RZ_LOG_ERROR("core: Injection opcodes so long\n"); - } - } - rz_reg_arena_pop(core->dbg->reg); - break; - case 's': // "dxs" - if (input[2]) { - char *str; - str = rz_core_cmd_str(core, sdb_fmt("gs %s", input + 2)); - rz_core_cmdf(core, "dx %s", str); //`gs %s`", input + 2); - free(str); - } else { - RZ_LOG_ERROR("core: Missing parameter used in gs by dxs\n"); - } - break; - case '?': // "dx?" - default: - rz_core_cmd_help(core, help_msg_dx); - break; - } - break; case '?': // "d?" default: rz_core_cmd_help(core, help_msg_d); @@ -3487,3 +3390,70 @@ RZ_IPI RzCmdStatus rz_cmd_debug_pid_signal_handler(RzCore *core, int argc, const rz_debug_kill(core->dbg, pid, false, sig); return RZ_CMD_STATUS_OK; } + +static bool debug_inject_opcode(RzCore *core, const char *opcode) { + if (strlen(opcode) >= 4096) { + RZ_LOG_ERROR("core: the opcodes to inject are too long (> 2048 bytes)\n"); + return false; + } + ut8 bytes[4096]; + int bytes_len = rz_hex_str2bin(opcode, bytes); + if (bytes_len <= 0) { + RZ_LOG_ERROR("core: Invalid hexpairs\n"); + return false; + } + rz_debug_execute(core->dbg, bytes, bytes_len, 0); + return true; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_inject_opcode_handler(RzCore *core, int argc, const char **argv) { + return bool2status(debug_inject_opcode(core, argv[1])); +} + +RZ_IPI RzCmdStatus rz_cmd_debug_inject_assembly_handler(RzCore *core, int argc, const char **argv) { + RzAsmCode *acode; + rz_asm_set_pc(core->rasm, core->offset); + acode = rz_asm_massemble(core->rasm, argv[1]); + if (acode) { + rz_reg_arena_push(core->dbg->reg); + rz_debug_execute(core->dbg, acode->bytes, acode->len, 0); + rz_reg_arena_pop(core->dbg->reg); + } + rz_asm_code_free(acode); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_inject_egg_handler(RzCore *core, int argc, const char **argv) { + RzEgg *egg = core->egg; + RzBuffer *b; + const char *asm_arch = rz_config_get(core->config, "asm.arch"); + int asm_bits = rz_config_get_i(core->config, "asm.bits"); + const char *asm_os = rz_config_get(core->config, "asm.os"); + rz_egg_setup(egg, asm_arch, asm_bits, 0, asm_os); + rz_egg_reset(egg); + rz_egg_load(egg, argv[1], 0); + rz_egg_compile(egg); + b = rz_egg_get_bin(egg); + rz_asm_set_pc(core->rasm, core->offset); + rz_reg_arena_push(core->dbg->reg); + ut64 tmpsz; + const ut8 *tmp = rz_buf_data(b, &tmpsz); + rz_debug_execute(core->dbg, tmp, tmpsz, 0); + rz_reg_arena_pop(core->dbg->reg); + return RZ_CMD_STATUS_OK; +} + +RZ_IPI RzCmdStatus rz_cmd_debug_inject_opcode_restore_handler(RzCore *core, int argc, const char **argv) { + rz_reg_arena_push(core->dbg->reg); + bool result = debug_inject_opcode(core, argv[1]); + rz_reg_arena_pop(core->dbg->reg); + return bool2status(result); +} + +RZ_IPI RzCmdStatus rz_cmd_debug_inject_syscall_handler(RzCore *core, int argc, const char **argv) { + // TODO: Use the API instead of the command + char *str = rz_core_cmd_str(core, rz_str_newf("gs %s", argv[1])); + bool result = debug_inject_opcode(core, str); + free(str); + return bool2status(result); +} diff --git a/librz/core/cmd_descs/cmd_debug.yaml b/librz/core/cmd_descs/cmd_debug.yaml index 19bc4ebb65a..9fef91f2ed5 100644 --- a/librz/core/cmd_descs/cmd_debug.yaml +++ b/librz/core/cmd_descs/cmd_debug.yaml @@ -1103,3 +1103,54 @@ commands: args: - name: number type: RZ_CMD_ARG_TYPE_NUM + - name: dx + summary: Code injection commands + subcommands: + - name: dx + summary: Inject opcodes + cname: cmd_debug_inject_opcode + args: + - name: opcode + type: RZ_CMD_ARG_TYPE_STRING + details: + - name: Examples + entries: + - text: dx + arg_str: " 9090" + comment: Insert two 0x90 bytes (nop instruction on x86 platforms) + - name: dxa + summary: Assemble code and inject + cname: cmd_debug_inject_assembly + args: + - name: asm + type: RZ_CMD_ARG_TYPE_STRING + details: + - name: Examples + entries: + - text: dxa + arg_str: " mov eax,6; mov ebx,0; int 0x80" + comment: Assemble and insert 3 instructions + - name: dxe + summary: Compile RzEgg expression and inject + cname: cmd_debug_inject_egg + args: + - name: expression + type: RZ_CMD_ARG_TYPE_STRING + - name: dxr + summary: Inject opcodes and restore state + cname: cmd_debug_inject_opcode_restore + args: + - name: opcode + type: RZ_CMD_ARG_TYPE_STRING + - name: dxs + summary: Syscall injection + cname: cmd_debug_inject_syscall + args: + - name: syscall + type: RZ_CMD_ARG_TYPE_STRING + details: + - name: Examples + entries: + - text: dxs + arg_str: " write 1, 0x8048, 12" + comment: Inject the write() syscall with given arguments diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index eeef1655e57..1d4361fcdf4 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -41,6 +41,9 @@ static const RzCmdDescDetail cmd_debug_add_cond_bp_details[2]; static const RzCmdDescDetail cmd_debug_add_watchpoint_details[2]; static const RzCmdDescDetail debug_reg_cond_details[4]; static const RzCmdDescDetail dr_details[2]; +static const RzCmdDescDetail cmd_debug_inject_opcode_details[2]; +static const RzCmdDescDetail cmd_debug_inject_assembly_details[2]; +static const RzCmdDescDetail cmd_debug_inject_syscall_details[2]; static const RzCmdDescDetail eval_getset_details[2]; static const RzCmdDescDetail egg_config_details[2]; static const RzCmdDescDetail history_list_or_exec_details[2]; @@ -371,6 +374,11 @@ static const RzCmdDescArg debug_reg_profile_open_args[2]; static const RzCmdDescArg debug_reg_profile_gdb_args[2]; static const RzCmdDescArg debug_drx_args[5]; static const RzCmdDescArg debug_drx_unset_args[2]; +static const RzCmdDescArg cmd_debug_inject_opcode_args[2]; +static const RzCmdDescArg cmd_debug_inject_assembly_args[2]; +static const RzCmdDescArg cmd_debug_inject_egg_args[2]; +static const RzCmdDescArg cmd_debug_inject_opcode_restore_args[2]; +static const RzCmdDescArg cmd_debug_inject_syscall_args[2]; static const RzCmdDescArg eval_getset_args[2]; static const RzCmdDescArg eval_list_args[2]; static const RzCmdDescArg eval_bool_invert_args[2]; @@ -8447,6 +8455,106 @@ static const RzCmdDescHelp debug_drx_unset_help = { .args = debug_drx_unset_args, }; +static const RzCmdDescHelp dx_help = { + .summary = "Code injection commands", +}; +static const RzCmdDescDetailEntry cmd_debug_inject_opcode_Examples_detail_entries[] = { + { .text = "dx", .arg_str = " 9090", .comment = "Insert two 0x90 bytes (nop instruction on x86 platforms)" }, + { 0 }, +}; +static const RzCmdDescDetail cmd_debug_inject_opcode_details[] = { + { .name = "Examples", .entries = cmd_debug_inject_opcode_Examples_detail_entries }, + { 0 }, +}; +static const RzCmdDescArg cmd_debug_inject_opcode_args[] = { + { + .name = "opcode", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_inject_opcode_help = { + .summary = "Inject opcodes", + .details = cmd_debug_inject_opcode_details, + .args = cmd_debug_inject_opcode_args, +}; + +static const RzCmdDescDetailEntry cmd_debug_inject_assembly_Examples_detail_entries[] = { + { .text = "dxa", .arg_str = " mov eax,6; mov ebx,0; int 0x80", .comment = "Assemble and insert 3 instructions" }, + { 0 }, +}; +static const RzCmdDescDetail cmd_debug_inject_assembly_details[] = { + { .name = "Examples", .entries = cmd_debug_inject_assembly_Examples_detail_entries }, + { 0 }, +}; +static const RzCmdDescArg cmd_debug_inject_assembly_args[] = { + { + .name = "asm", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_inject_assembly_help = { + .summary = "Assemble code and inject", + .details = cmd_debug_inject_assembly_details, + .args = cmd_debug_inject_assembly_args, +}; + +static const RzCmdDescArg cmd_debug_inject_egg_args[] = { + { + .name = "expression", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_inject_egg_help = { + .summary = "Compile RzEgg expression and inject", + .args = cmd_debug_inject_egg_args, +}; + +static const RzCmdDescArg cmd_debug_inject_opcode_restore_args[] = { + { + .name = "opcode", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_inject_opcode_restore_help = { + .summary = "Inject opcodes and restore state", + .args = cmd_debug_inject_opcode_restore_args, +}; + +static const RzCmdDescDetailEntry cmd_debug_inject_syscall_Examples_detail_entries[] = { + { .text = "dxs", .arg_str = " write 1, 0x8048, 12", .comment = "Inject the write() syscall with given arguments" }, + { 0 }, +}; +static const RzCmdDescDetail cmd_debug_inject_syscall_details[] = { + { .name = "Examples", .entries = cmd_debug_inject_syscall_Examples_detail_entries }, + { 0 }, +}; +static const RzCmdDescArg cmd_debug_inject_syscall_args[] = { + { + .name = "syscall", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + + }, + { 0 }, +}; +static const RzCmdDescHelp cmd_debug_inject_syscall_help = { + .summary = "Syscall injection", + .details = cmd_debug_inject_syscall_details, + .args = cmd_debug_inject_syscall_args, +}; + static const RzCmdDescHelp e_help = { .summary = "List/get/set config evaluable vars", }; @@ -16971,6 +17079,20 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *debug_drx_unset_cd = rz_cmd_desc_argv_new(core->rcmd, drx_cd, "drx-", rz_debug_drx_unset_handler, &debug_drx_unset_help); rz_warn_if_fail(debug_drx_unset_cd); + RzCmdDesc *dx_cd = rz_cmd_desc_group_new(core->rcmd, cmd_debug_cd, "dx", rz_cmd_debug_inject_opcode_handler, &cmd_debug_inject_opcode_help, &dx_help); + rz_warn_if_fail(dx_cd); + RzCmdDesc *cmd_debug_inject_assembly_cd = rz_cmd_desc_argv_new(core->rcmd, dx_cd, "dxa", rz_cmd_debug_inject_assembly_handler, &cmd_debug_inject_assembly_help); + rz_warn_if_fail(cmd_debug_inject_assembly_cd); + + RzCmdDesc *cmd_debug_inject_egg_cd = rz_cmd_desc_argv_new(core->rcmd, dx_cd, "dxe", rz_cmd_debug_inject_egg_handler, &cmd_debug_inject_egg_help); + rz_warn_if_fail(cmd_debug_inject_egg_cd); + + RzCmdDesc *cmd_debug_inject_opcode_restore_cd = rz_cmd_desc_argv_new(core->rcmd, dx_cd, "dxr", rz_cmd_debug_inject_opcode_restore_handler, &cmd_debug_inject_opcode_restore_help); + rz_warn_if_fail(cmd_debug_inject_opcode_restore_cd); + + RzCmdDesc *cmd_debug_inject_syscall_cd = rz_cmd_desc_argv_new(core->rcmd, dx_cd, "dxs", rz_cmd_debug_inject_syscall_handler, &cmd_debug_inject_syscall_help); + rz_warn_if_fail(cmd_debug_inject_syscall_cd); + RzCmdDesc *e_cd = rz_cmd_desc_group_new(core->rcmd, root_cd, "e", rz_eval_getset_handler, &eval_getset_help, &e_help); rz_warn_if_fail(e_cd); RzCmdDesc *eval_list_cd = rz_cmd_desc_argv_state_new(core->rcmd, e_cd, "el", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_LONG | RZ_OUTPUT_MODE_LONG_JSON, rz_eval_list_handler, &eval_list_help); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index c7ca81943c1..67ba795cd37 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -585,6 +585,11 @@ RZ_IPI RzCmdStatus rz_debug_reg_types_handler(RzCore *core, int argc, const char RZ_IPI RzCmdStatus rz_debug_reg_roles_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_debug_drx_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_debug_drx_unset_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_inject_opcode_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_inject_assembly_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_inject_egg_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_inject_opcode_restore_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdStatus rz_cmd_debug_inject_syscall_handler(RzCore *core, int argc, const char **argv); RZ_IPI int rz_cmd_debug(void *data, const char *input); RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **argv); RZ_IPI RzCmdStatus rz_eval_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);