Export pcA as rz_core_print_bytes_with_inst (#2880)

* export `rz_core_print_bytes_with_inst`
* move `pcA` to rzshell
This commit is contained in:
billow 2022-08-07 00:28:01 +08:00 committed by GitHub
parent dc8cd44db4
commit 1054e6295f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 115 deletions

View file

@ -28,31 +28,6 @@ static const char *help_msg_pp[] = {
NULL
};
static const char *help_msg_pc[] = {
"Usage:", "pc", " # Print in code",
"pc", "", "C",
"pc*", "", "print 'wx' rizin commands",
"pcA", "", ".bytes with instructions in comments",
"pca", "", "GAS .byte blob",
"pcd", "", "C dwords (8 byte)",
"pch", "", "C half-words (2 byte)",
"pci", "", "C array of bytes with instructions",
"pcJ", "", "javascript",
"pcj", "", "json",
"pck", "", "kotlin",
"pco", "", "Objective-C",
"pcp", "", "python",
"pcr", "", "rust",
"pcS", "", "shellscript that reconstructs the bin",
"pcs", "", "string",
"pcv", "", "JaVa",
"pcV", "", "V (vlang.io)",
"pcw", "", "C words (4 byte)",
"pcy", "", "yara",
"pcz", "", "Swift",
NULL
};
static const char *help_msg_pF[] = {
"Usage: pF[apdbA]", "[len]", "parse ASN1, PKCS, X509, DER, protobuf, axml",
"pFa", "[len]", "decode ASN1 from current block",
@ -5335,96 +5310,6 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) {
}
}
break;
case 'c': // "pc"
if (input[1] == '?') {
rz_core_cmd_help(core, help_msg_pc);
} else if (l) {
const ut8 *buf = core->block;
int i = 0;
int j = 0;
if (input[1] == 'A') { // "pcA"
rz_cons_printf("sub_0x%08" PFMT64x ":\n", core->offset);
for (i = 0; i < len; i++) {
RzAsmOp asmop = {
0
};
(void)rz_asm_disassemble(core->rasm, &asmop, buf + i, len - i);
int sz = asmop.size;
if (sz < 1) {
sz = 1;
}
rz_cons_printf(" .byte ");
for (j = 0; j < sz; j++) {
rz_cons_printf("%s0x%02x", j ? ", " : "", buf[i]);
i++;
}
rz_cons_printf(" // %s\n", rz_strbuf_get(&asmop.buf_asm));
i--;
}
rz_cons_printf(".equ shellcode_len, %d\n", len);
} else {
char *str = NULL;
bool big_endian = rz_config_get_b(core->config, "cfg.bigendian");
switch (input[1]) {
case '*': // "pc*" // rizin commands
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_RIZIN);
break;
case 'a': // "pca" // GAS asm
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_ASM);
break;
case 'b': // "pcb" // bash shellscript
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_BASH);
break;
case 'n': // "pcn" // nodejs
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_NODEJS);
break;
case 'g': // "pcg" // golang
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_GOLANG);
break;
case 'k': // "pck" kotlin
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_KOTLIN);
break;
case 's': // "pcs" // swift
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_SWIFT);
break;
case 'r': // "pcr" // Rust
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_RUST);
break;
case 'o': // "pco" // Objective-C
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_OBJECTIVE_C);
break;
case 'J': // "pcJ" // java
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_JAVA);
break;
case 'y': // "pcy" // yara
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_YARA);
break;
case 'j': // "pcj" // json
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_JSON);
break;
case 'p': // "pcp" // python
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_PYTHON);
break;
case 'h': // "pch" // C half words with asm
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, big_endian ? RZ_LANG_BYTE_ARRAY_C_CPP_HALFWORDS_BE : RZ_LANG_BYTE_ARRAY_C_CPP_HALFWORDS_LE);
break;
case 'w': // "pcw" // C words with asm
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, big_endian ? RZ_LANG_BYTE_ARRAY_C_CPP_WORDS_BE : RZ_LANG_BYTE_ARRAY_C_CPP_WORDS_LE);
break;
case 'd': // "pcd" // C double-words with asm
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, big_endian ? RZ_LANG_BYTE_ARRAY_C_CPP_DOUBLEWORDS_BE : RZ_LANG_BYTE_ARRAY_C_CPP_DOUBLEWORDS_LE);
break;
default: // "pc" // C bytes
str = rz_lang_byte_array(core->block, len < 0 ? 0 : len, RZ_LANG_BYTE_ARRAY_C_CPP_BYTES);
break;
}
if (str) {
rz_cons_println(str);
free(str);
}
}
}
break;
case 'C': // "pC"
switch (input[1]) {
case 0:
@ -6251,6 +6136,17 @@ CMD_PRINT_BYTE_ARRAY_HANDLER_NORMAL(rz_cmd_print_byte_array_yara_handler, RZ_LAN
#undef CMD_PRINT_BYTE_ARRAY_HANDLER_NORMAL
#undef CMD_PRINT_BYTE_ARRAY_HANDLER_ENDIAN
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_with_inst_handler(RzCore *core, int argc, const char **argv) {
rz_core_block_read(core);
char *code = rz_core_print_bytes_with_inst(core, core->block, core->offset, (int)core->blocksize);
if (!code) {
return RZ_CMD_STATUS_ERROR;
}
rz_cons_println(code);
free(code);
return RZ_CMD_STATUS_OK;
}
static void disassembly_as_table(RzTable *t, RzCore *core, int n_instrs, int n_bytes) {
ut8 buffer[256];
rz_table_set_columnsf(t, "snssssss", "name", "addr", "bytes", "disasm", "comment", "esil", "refs", "xrefs");

View file

@ -10610,6 +10610,14 @@ static const RzCmdDescHelp cmd_print_byte_array_asm_help = {
.args = cmd_print_byte_array_asm_args,
};
static const RzCmdDescArg cmd_print_byte_array_with_inst_args[] = {
{ 0 },
};
static const RzCmdDescHelp cmd_print_byte_array_with_inst_help = {
.summary = "Generate a byte array in GAS assembly with instructions in comments",
.args = cmd_print_byte_array_with_inst_args,
};
static const RzCmdDescArg cmd_print_byte_array_bash_args[] = {
{ 0 },
};
@ -16817,6 +16825,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *cmd_print_byte_array_asm_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_byte_array_cd, "pca", rz_cmd_print_byte_array_asm_handler, &cmd_print_byte_array_asm_help);
rz_warn_if_fail(cmd_print_byte_array_asm_cd);
RzCmdDesc *cmd_print_byte_array_with_inst_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_byte_array_cd, "pcA", rz_cmd_print_byte_array_with_inst_handler, &cmd_print_byte_array_with_inst_help);
rz_warn_if_fail(cmd_print_byte_array_with_inst_cd);
RzCmdDesc *cmd_print_byte_array_bash_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_byte_array_cd, "pcb", rz_cmd_print_byte_array_bash_handler, &cmd_print_byte_array_bash_help);
rz_warn_if_fail(cmd_print_byte_array_bash_cd);

View file

@ -768,6 +768,7 @@ RZ_IPI RzCmdStatus rz_cmd_print_byte_array_c_cpp_half_word_handler(RzCore *core,
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_c_cpp_word_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_c_cpp_double_word_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_asm_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_with_inst_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_bash_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_golang_handler(RzCore *core, int argc, const char **argv);
RZ_IPI RzCmdStatus rz_cmd_print_byte_array_java_handler(RzCore *core, int argc, const char **argv);

View file

@ -100,6 +100,10 @@ commands:
summary: Generate a byte array in GAS assembly.
cname: cmd_print_byte_array_asm
args: []
- name: pcA
summary: Generate a byte array in GAS assembly with instructions in comments
cname: cmd_print_byte_array_with_inst
args: []
- name: pcb
summary: Generate a bash script with the byte array.
cname: cmd_print_byte_array_bash

View file

@ -473,3 +473,35 @@ RZ_IPI bool rz_core_print_hexdump_byline(RZ_NONNULL RzCore *core, bool hexoffset
free(string);
return true;
}
/**
* \brief Bytes string at \p addr with instructions in comments
*/
RZ_API RZ_OWN char *rz_core_print_bytes_with_inst(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, ut64 addr, int len) {
rz_return_val_if_fail(core && buf, NULL);
RzStrBuf *sb = rz_strbuf_new(NULL);
if (!sb) {
return NULL;
}
rz_strbuf_appendf(sb, "sub_0x%08" PFMT64x ":\n", addr);
for (int i = 0; i < len; i++) {
RzAsmOp asmop = {
0
};
(void)rz_asm_disassemble(core->rasm, &asmop, buf + i, len - i);
int sz = asmop.size;
if (sz < 1) {
sz = 1;
}
rz_strbuf_appendf(sb, " .byte ");
for (int j = 0; j < sz && i < len; j++) {
rz_strbuf_appendf(sb, "%s0x%02x", j ? ", " : "", buf[i]);
i++;
}
rz_strbuf_appendf(sb, " // %s\n", rz_strbuf_get(&asmop.buf_asm));
rz_asm_op_fini(&asmop);
i--;
}
rz_strbuf_appendf(sb, ".equ shellcode_len, %d", len);
return rz_strbuf_drain(sb);
}

View file

@ -1073,6 +1073,7 @@ RZ_API RZ_OWN char *rz_core_print_hexdump_diff_str(RZ_NONNULL RzCore *core, ut64
RZ_API RZ_OWN char *rz_core_print_dump_str(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, ut8 n, int len, RzCorePrintFormatType format);
RZ_API RZ_OWN char *rz_core_print_hexdump_or_hexdiff_str(RZ_NONNULL RzCore *core, RzOutputMode mode, ut64 addr, int len, bool use_comment);
RZ_API RZ_OWN char *rz_core_print_hexdump_byline_str(RZ_NONNULL RzCore *core, bool hex_offset, ut64 addr, int len, ut8 size);
RZ_API RZ_OWN char *rz_core_print_bytes_with_inst(RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, ut64 addr, int len);
/* rtr */
RZ_API bool rz_core_rtr_init(RZ_NONNULL RzCore *core);

View file

@ -160,6 +160,23 @@ byte_array:
EOF
RUN
NAME=Print bytes as assembly with instructions in comments.
FILE=bins/elf/analysis/hello-arm32
CMDS=pcA @! 30
EXPECT=<<EOF
sub_0x000101c0:
.byte 0x80, 0x40, 0x2d, 0xe9 // push {r7, lr}
.byte 0x00, 0x70, 0x8d, 0xe2 // add r7, sp, 0
.byte 0x00, 0x02, 0x00, 0xe3 // movw r0, 0x200
.byte 0x01, 0x00, 0x40, 0xe3 // movt r0, 1
.byte 0xf1, 0xff, 0xff, 0xeb // bl 0xffffffcc
.byte 0x00, 0x30, 0xb0, 0xe3 // movs r3, 0
.byte 0x03, 0x00, 0xa0, 0xe1 // mov r0, r3
.byte 0xf1, 0xff // invalid
.equ shellcode_len, 30
EOF
RUN
NAME=Print bytes as a bash command.
FILE=bins/elf/analysis/hello-arm32
CMDS=pcb @! 30