Implement pfc C struct format command ##print

This commit is contained in:
Óscar Carrasco 2019-04-13 15:09:29 +01:00 committed by radare
parent 7db114ab61
commit 73e36a9719
3 changed files with 84 additions and 0 deletions

View File

@ -299,6 +299,7 @@ static const char *help_msg_pf[] = {
"pf", " fmt", "Show data using the given format-string. See 'pf\?\?' and 'pf\?\?\?'.",
"pf.", "fmt_name", "Show data using named format",
"pf.", "fmt_name.field_name", "Show specific data field using named format",
"pfc ", "fmt_name|fmt", "Show data using (named) format as C string",
"pfj ", "fmt_name|fmt", "Show data using (named) format in JSON",
"pf* ", "fmt_name|fmt", "Show data using (named) format as r2 flag create commands",
"pfd.", "fmt_name", "Show data using named format as graphviz commands",
@ -1159,6 +1160,10 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block,
_input++;
mode = R_PRINT_VALUE | R_PRINT_MUSTSEE;
break;
case 'c': // "pfc"
_input++;
mode = R_PRINT_STRUCT;
break;
case 's': { // "pfs"
const char *val = NULL;
_input += 2;

View File

@ -169,6 +169,7 @@ R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang);
#define R_PRINT_VALUE (1 << 6)
#define R_PRINT_DOT (1 << 7)
#define R_PRINT_QUIET (1 << 8)
#define R_PRINT_STRUCT (1 << 9)
R_API int r_print_format_struct_size(const char *format, RPrint *p, int mode, int n);
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* buf, const int len, const char *fmt, int elem, const char *setval, char *field);
R_API int r_print_format_length(const char *fmt);

View File

@ -1767,6 +1767,58 @@ static char* get_args_offset(const char *arg) {
return args;
}
static char* get_format_type(const char fmt) {
char *type = NULL;
switch (fmt) {
case 'b':
case 'C':
type = strdup ("unsigned char");
break;
case 'c':
type = strdup ("char");
break;
case 'd':
type = strdup ("unsigned int");
break;
case 'f':
type = strdup ("float");
break;
case 'F':
type = strdup ("double");
break;
case 'i':
case 'o':
type = strdup ("int");
break;
case 'p':
type = strdup ("void*");
break;
case 'q':
type = strdup ("long long");
break;
case 'u':
type = strdup ("uleb128_t");
break;
case 'w':
type = strdup ("unsigned short");
break;
case 'x':
type = strdup ("long");
break;
case 'X':
type = strdup ("unsigned char[]");
break;
case 'D':
case 's':
case 'S':
case 't':
case 'z':
case 'Z':
type = strdup ("char*");
}
return type;
}
#define MINUSONE ((void*)(size_t)-1)
#define ISSTRUCT (tmp == '?' || (tmp == '*' && *(arg+1) == '?'))
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
@ -1872,6 +1924,17 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
if (mode == R_PRINT_JSON && slide == 0) {
p->cb_printf ("[");
}
if (mode == R_PRINT_STRUCT) {
if (formatname && *formatname) {
if (strchr (formatname, ' ')) {
p->cb_printf ("struct {\n");
} else {
p->cb_printf ("struct %s {\n", formatname);
}
} else {
p->cb_printf ("struct {\n");
}
}
if (mode && arg[0] == '0') {
mode |= R_PRINT_UNIONMODE;
arg++;
@ -2185,6 +2248,15 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
p->cb_printf ("\",\"offset\":%d,\"value\":",
isptr? (seek + nexti - (p->bits / 8)) : seek + i);
}
/* c struct */
if (mode & R_PRINT_STRUCT) {
char *type = get_format_type (tmp);
if (type) {
p->cb_printf (" %s %s;", type, fieldname);
}
free (type);
}
bool noline = false;
int oi = i;
@ -2471,6 +2543,9 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
break;
} //switch
}
if (mode & R_PRINT_STRUCT) {
p->cb_printf ("\n");
}
if (mode & R_PRINT_DOT) {
p->cb_printf ("}");
}
@ -2526,6 +2601,9 @@ R_API int r_print_format(RPrint *p, ut64 seek, const ut8* b, const int len,
if (mode & R_PRINT_JSON && slide == 0) {
p->cb_printf("]\n");
}
if (mode & R_PRINT_STRUCT) {
p->cb_printf ("}\n");
}
if (mode & R_PRINT_DOT) {
p->cb_printf ("\"];\n}\n");
// TODO: show nested structs and field reference lines