From 02398e1e1782f3a19bb7f5551cf5b1c68cb2936b Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 26 Apr 2017 19:35:37 +0200 Subject: [PATCH] Implement r2 -X to specify custom rarun2 directives --- binr/radare2/radare2.c | 20 ++++++++++++++++++-- libr/core/disasm.c | 4 ++-- libr/include/r_socket.h | 5 ++--- libr/io/p/io_debug.c | 2 +- libr/socket/run.c | 41 ++++++++++++++++++++++++----------------- libr/util/file.c | 3 +++ man/radare2.1 | 4 +++- 7 files changed, 53 insertions(+), 26 deletions(-) diff --git a/binr/radare2/radare2.c b/binr/radare2/radare2.c index df556cebd5..1dd4c38a0c 100644 --- a/binr/radare2/radare2.c +++ b/binr/radare2/radare2.c @@ -129,7 +129,7 @@ static ut64 getBaddrFromDebugger(RCore *r, const char *file) { static int main_help(int line) { if (line < 2) { - printf ("Usage: r2 [-ACdfLMnNqStuvwz] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]\n" + printf ("Usage: r2 [-ACdfLMnNqStuvwzX] [-P patch] [-p prj] [-a arch] [-b bits] [-i file]\n" " [-s addr] [-B baddr] [-M maddr] [-c cmd] [-e k=v] file|pid|-|--|=\n"); } if (line != 1) { @@ -174,6 +174,7 @@ static int main_help(int line) { " -u set bin.filter=false to get raw sym/sec/cls names\n" " -v, -V show radare2 version (-V show lib versions)\n" " -w open file in write mode\n" + " -X [rr2rule] specify custom rarun2 directive\n" " -z, -zz do not load strings or load them even in raw\n"); } if (line == 2) { @@ -445,6 +446,7 @@ int main(int argc, char **argv, char **envp) { const char *asmos = NULL; const char *forcebin = NULL; const char *asmbits = NULL; + char *customRarunProfile = NULL; ut64 mapaddr = 0LL; bool quiet = false; bool quietLeak = false; @@ -491,7 +493,7 @@ int main(int argc, char **argv, char **envp) { return 0; } - while ((c = getopt (argc, argv, "=02AMCwfF:H:hm:e:nk:NdqQs:p:b:B:a:Lui:I:l:P:R:c:D:vVSzu" + while ((c = getopt (argc, argv, "=02AMCwfF:H:hm:e:nk:NdqQs:p:b:B:a:Lui:I:l:P:R:c:D:vVSzuX:" #if USE_THREADS "t" #endif @@ -646,6 +648,9 @@ int main(int argc, char **argv, char **envp) { case 'w': perms = R_IO_READ | R_IO_WRITE; break; + case 'X': + customRarunProfile = r_str_appendf (customRarunProfile, "%s\n", optarg); + break; default: help++; } @@ -702,6 +707,17 @@ int main(int argc, char **argv, char **envp) { r_list_free (cmds); return main_help (help > 1? 2: 0); } + if (customRarunProfile) { + char *tfn = "/tmp/puta"; //r_file_temp (NULL); + if (!r_file_dump (tfn, (const ut8*)customRarunProfile, strlen (customRarunProfile), 0)) { + eprintf ("Cannot create %s\n", tfn); + } else { + haveRarunProfile = true; + r_config_set (r.config, "dbg.profile", tfn); + } + // TODO: must be removed or just dont use a temporary file + // TODO this current code is leaking temporary files and memory + } if (debug == 1) { if (optind >= argc && !haveRarunProfile) { eprintf ("Missing argument for -d\n"); diff --git a/libr/core/disasm.c b/libr/core/disasm.c index bd697a338f..255219e436 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -4757,7 +4757,7 @@ R_API int r_core_disasm_pdi(RCore *core, int nb_opcodes, int nb_bytes, int fmt) char opstr[128] = { 0 }; - char *asm_str = &asmop.buf_asm; + char *asm_str = asmop.buf_asm; if (filter && asm_ucase) { r_str_case (asm_str, 1); @@ -4766,7 +4766,7 @@ R_API int r_core_disasm_pdi(RCore *core, int nb_opcodes, int nb_bytes, int fmt) if (filter) { r_parse_filter (core->parser, core->flags, asm_str, opstr, sizeof (opstr) - 1, core->print->big_endian); - asm_str = &opstr; + asm_str = (char *)&opstr; } if (show_color) { diff --git a/libr/include/r_socket.h b/libr/include/r_socket.h index 758568f41c..bdc6999ac2 100644 --- a/libr/include/r_socket.h +++ b/libr/include/r_socket.h @@ -215,10 +215,9 @@ typedef struct r_run_profile_t { } RRunProfile; R_API RRunProfile *r_run_new(const char *str); -R_API int r_run_parseline (RRunProfile *p, char *b); -R_API int r_run_parse(RRunProfile *pf, const char *profile); +R_API bool r_run_parse(RRunProfile *pf, const char *profile); R_API void r_run_free (RRunProfile *r); -R_API int r_run_parseline (RRunProfile *p, char *b); +R_API bool r_run_parseline (RRunProfile *p, char *b); R_API const char *r_run_help(void); R_API int r_run_config_env(RRunProfile *p); R_API int r_run_start(RRunProfile *p); diff --git a/libr/io/p/io_debug.c b/libr/io/p/io_debug.c index ba5b3bdeef..358146d2a1 100644 --- a/libr/io/p/io_debug.c +++ b/libr/io/p/io_debug.c @@ -227,7 +227,7 @@ static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) { rp->_args[i] = argv[i]; } rp->_args[i] = NULL; - rp->_program = argv[0]; + rp->_program = strdup (argv[0]); rp->_dodebug = true; if (io->runprofile && *io->runprofile) { if (!r_run_parsefile (rp, io->runprofile)) { diff --git a/libr/socket/run.c b/libr/socket/run.c index c155f71458..fd5dbad6ec 100644 --- a/libr/socket/run.c +++ b/libr/socket/run.c @@ -57,10 +57,10 @@ #endif R_API RRunProfile *r_run_new(const char *str) { - RRunProfile *p = R_NEW (RRunProfile); + RRunProfile *p = R_NEW0 (RRunProfile); if (p) { r_run_reset (p); - if (str) r_run_parsefile (p, str); + r_run_parsefile (p, str); } return p; } @@ -70,10 +70,13 @@ R_API void r_run_reset(RRunProfile *p) { p->_aslr = -1; } -R_API int r_run_parse(RRunProfile *pf, const char *profile) { +R_API bool r_run_parse(RRunProfile *pf, const char *profile) { + if (!pf || !profile) { + return false; + } char *p, *o, *str = strdup (profile); if (!str) { - return 0; + return false; } r_str_replace_char (str, '\r',0); for (o = p = str; (o = strchr (p, '\n')); p = o) { @@ -81,7 +84,7 @@ R_API int r_run_parse(RRunProfile *pf, const char *profile) { r_run_parseline (pf, p); } free (str); - return 1; + return true; } R_API void r_run_free (RRunProfile *r) { @@ -263,9 +266,7 @@ static int handle_redirection_proc (const char *cmd, bool in, bool out, bool err // case of interactive programs. int saved_stdin = dup (STDIN_FILENO); int saved_stdout = dup (STDOUT_FILENO); - - int fdm; - int pid = forkpty (&fdm, NULL, NULL, NULL); + int fdm, pid = forkpty (&fdm, NULL, NULL, NULL); if (in) { dup2 (fdm, STDIN_FILENO); } @@ -357,17 +358,20 @@ R_API int r_run_parsefile (RRunProfile *p, const char *b) { return 0; } -R_API int r_run_parseline (RRunProfile *p, char *b) { +R_API bool r_run_parseline (RRunProfile *p, char *b) { int must_free = false; char *e = strchr (b, '='); - if (!e) return 0; - if (*b=='#') return 0; + if (!e || *b == '#') { + return 0; + } *e++ = 0; if (*e=='$') { must_free = true; e = r_sys_getenv (e); } - if (!e) return 0; + if (!e) { + return 0; + } if (!strcmp (b, "program")) p->_args[0] = p->_program = strdup (e); else if (!strcmp (b, "system")) p->_system = strdup (e); else if (!strcmp (b, "aslr")) p->_aslr = parseBool (e); @@ -421,11 +425,13 @@ R_API int r_run_parseline (RRunProfile *p, char *b) { FILE *fd = fopen (e, "r"); if (!fd) { eprintf ("Cannot open '%s'\n", e); - if (must_free == true) free (e); - return 0; + if (must_free == true) { + free (e); + } + return false; } for (;;) { - fgets (buf, sizeof (buf)-1, fd); + fgets (buf, sizeof (buf) - 1, fd); if (feof (fd)) break; p = strchr (buf, '='); if (p) { @@ -447,9 +453,10 @@ R_API int r_run_parseline (RRunProfile *p, char *b) { } else if (!strcmp(b, "clearenv")) { r_sys_clearenv (); } - if (must_free == true) + if (must_free == true) { free (e); - return 1; + } + return true; } R_API const char *r_run_help() { diff --git a/libr/util/file.c b/libr/util/file.c index 0130566290..e879774f87 100644 --- a/libr/util/file.c +++ b/libr/util/file.c @@ -808,6 +808,9 @@ R_API char *r_file_temp (const char *prefix) { int namesz; char *name; char *path = r_file_tmpdir (); + if (!prefix) { + prefix = ""; + } namesz = strlen (prefix) + strlen (path) + 32; name = malloc (namesz); snprintf (name, namesz, "%s/%s.%"PFMT64x, path, prefix, r_sys_now ()); diff --git a/man/radare2.1 b/man/radare2.1 index bec0ab3db8..2c0a50df9f 100644 --- a/man/radare2.1 +++ b/man/radare2.1 @@ -18,7 +18,7 @@ .Op Fl P Ar patch .Op Fl R Ar rarun2 .Op Fl s Ar addr -.Op Fl 0AdDwntLquvV +.Op Fl 0AdDwntLquvVX .Ar -|--|=|file .Sh DESCRIPTION radare2 is a commandline hexadecimal editor. @@ -103,6 +103,8 @@ Open in write mode Show help message .It Fl H Show files and environment help +.It Fl X Ar rarun2-directive +Specify custom rarun2 directives without having to create a rarun2 profile .El .Sh SHELL Type '?' for help