static void visual_repeat(RCore *core) { int atport = r_config_get_i (core->config, "scr.atport"); if (atport) { #if __UNIX__ && !__APPLE__ int port = r_config_get_i (core->config, "http.port"); if (!r_core_rtr_http (core, '&', NULL)) { const char *xterm = r_config_get (core->config, "cmd.xterm"); // TODO: this must be configurable r_sys_cmdf ("%s 'r2 -C http://localhost:%d/cmd/V;sleep 1' &", xterm, port); //xterm -bg black -fg gray -e 'r2 -C http://localhost:%d/cmd/;sleep 1' &", port); } else { r_cons_any_key (NULL); } #else eprintf ("Unsupported on this platform\n"); r_cons_any_key (NULL); #endif } else { RThread *th = r_th_new (visual_repeat_thread, core, 0); r_th_start (th, 1); r_cons_break (NULL, NULL); r_cons_any_key (NULL); eprintf ("^C \n"); core->cons->breaked = true; r_th_wait (th); r_cons_break_end (); } }
R_API int r_socket_spawn (RSocket *s, const char *cmd, unsigned int timeout) { // XXX TODO: dont use sockets, we can achieve the same with pipes const int port = 2000 + r_num_rand (2000); int childPid = r_sys_fork(); if (childPid == 0) { char *a = r_str_replace (strdup (cmd), "\\", "\\\\", true); r_sys_cmdf ("rarun2 system=\"%s\" listen=%d", a, port); free (a); #if 0 // TODO: use the api char *profile = r_str_newf ( "system=%s\n" "listen=%d\n", cmd, port); RRunProfile *rp = r_run_new (profile); r_run_start (rp); r_run_free (rp); free (profile); #endif eprintf ("r_socket_spawn: %s is dead\n", cmd); exit (0); } r_sys_sleep (1); r_sys_usleep (timeout); char aport[32]; sprintf (aport, "%d", port); // redirect stdin/stdout/stderr return r_socket_connect (s, "127.0.0.1", aport, R_SOCKET_PROTO_TCP, 2000); }
static int __close(RIODesc *fd) { if (!fd || !fd->data) { return -1; } // XXX r_sys_cmdf ("pkill rarun2"); return 0; }
static int assemble(RAsm *a, RAsmOp *op, const char *buf) { char *ipath, *opath; int ifd, ofd; const char *syntaxstr = ""; char asm_buf[R_ASM_BUFSIZE]; int len = 0; ifd = r_file_mkstemp ("r_as", &ipath); ofd = r_file_mkstemp ("r_as", &opath); syntaxstr = ".intel_syntax noprefix\n"; // if intel syntax len = snprintf (asm_buf, sizeof (asm_buf), "%s.code%i\n" //.org 0x%"PFMT64x"\n" ".ascii \"BEGINMARK\"\n" "%s\n" ".ascii \"ENDMARK\"\n", syntaxstr, a->bits, buf); // a->pc ?? write (ifd, asm_buf, len); //write (1, asm_buf, len); close (ifd); if (!r_sys_cmdf ("as %s -o %s", ipath, opath)) { const ut8 *begin, *end; close (ofd); ofd = open (opath, O_BINARY|O_RDONLY); len = read (ofd, op->buf, R_ASM_BUFSIZE); begin = r_mem_mem (op->buf, len, (const ut8*)"BEGINMARK", 9); end = r_mem_mem (op->buf, len, (const ut8*)"ENDMARK", 7); if (!begin || !end) { eprintf ("Cannot find water marks\n"); len = 0; } else { len = (int)(size_t)(end-begin-9); if (len>0) memcpy (op->buf, begin+9, len); else len = 0; } } else { eprintf ("Error running: as %s -o %s", ipath, opath); len = 0; } close (ofd); unlink (ipath); unlink (opath); free (ipath); free (opath); op->inst_len = len; return len; }
R_API bool r_socket_spawn(RSocket *s, const char *cmd, unsigned int timeout) { // XXX TODO: dont use sockets, we can achieve the same with pipes const int port = 2000 + r_num_rand (2000); int childPid = r_sys_fork (); if (childPid == 0) { char *a = r_str_replace (strdup (cmd), "\\", "\\\\", true); int res = r_sys_cmdf ("rarun2 system=\"%s\" listen=%d", a, port); free (a); #if 0 // TODO: use the api char *profile = r_str_newf ( "system=%s\n" "listen=%d\n", cmd, port); RRunProfile *rp = r_run_new (profile); r_run_start (rp); r_run_free (rp); free (profile); #endif if (res != 0) { eprintf ("r_socket_spawn: rarun2 failed\n"); exit (1); } eprintf ("r_socket_spawn: %s is dead\n", cmd); exit (0); } r_sys_sleep (1); r_sys_usleep (timeout); char aport[32]; sprintf (aport, "%d", port); // redirect stdin/stdout/stderr bool sock = r_socket_connect (s, "127.0.0.1", aport, R_SOCKET_PROTO_TCP, 2000); if (!sock) { return false; } #if __UNIX__ r_sys_sleep (4); r_sys_usleep (timeout); int status = 0; int ret = waitpid (childPid, &status, WNOHANG); if (ret != 0) { r_socket_close (s); return false; } #endif return true; }
R_API bool r_sys_tts(const char *txt, bool bg) { int i; const char *says[] = { "say", "termux-tts-speak", NULL }; for (i = 0; says[i]; i++) { char *sayPath = r_file_path (says[i]); if (sayPath) { char *line = r_str_replace (strdup (txt), "'", "\"", 1); r_sys_cmdf ("\"%s\" '%s'%s", sayPath, line, bg? " &": ""); free (line); free (sayPath); return true; } } return false; }
static int assemble(RAsm *a, RAsmOp *op, const char *buf) { char *ipath, *opath; int ifd, ofd; char asm_buf[R_ASM_BUFSIZE]; int len = 0; if (a->syntax != R_ASM_SYNTAX_INTEL) { eprintf ("asm.x86.nasm does not support non-intel syntax\n"); return -1; } ifd = r_file_mkstemp ("r_nasm", &ipath); if (ifd == -1) return -1; ofd = r_file_mkstemp ("r_nasm", &opath); if (ofd == -1) { free (ipath); return -1; } len = snprintf (asm_buf, sizeof (asm_buf), "[BITS %i]\nORG 0x%"PFMT64x"\n%s\n", a->bits, a->pc, buf); write (ifd, asm_buf, len); close (ifd); if ( !r_sys_cmdf ("nasm %s -o %s", ipath, opath)) { len = read (ofd, op->buf, R_ASM_BUFSIZE); } else { eprintf ("Error running 'nasm'\n"); len = 0; } close (ofd); unlink (ipath); unlink (opath); free (ipath); free (opath); op->size = len; return len; }
static int cmd_project(void *data, const char *input) { RCore *core = (RCore *) data; const char *file, *arg = (input && *input)? input + 1: NULL; const char *fileproject = r_config_get (core->config, "prj.name"); char *str = NULL; if (!input) { return false; } str = strdup (fileproject); arg = strchr (input, ' '); if (arg) { arg++; } else { if (*input) { arg = input + 1; if (*arg == '&') { arg++; } } } file = arg; switch (input[0]) { case 'c': if (input[1] == ' ') { r_core_project_cat (core, input + 2); } else { eprintf ("Usage: Pc [prjname]\n"); } break; case 'o': // if (r_file_is_regular (file)) if (input[1] == '&') { r_core_project_open (core, file, true); } else if (input[1]) { r_core_project_open (core, file, false); } else { if (file && *file) { r_cons_println (file); } } break; case 'l': r_core_project_list (core, input[1]); break; case 'd': case '-': r_core_project_delete (core, file); break; case 's': if (!file || !file[0]) { /* if no argument specified use current project */ file = str; } if (r_core_project_save (core, file)) { r_config_set (core->config, "prj.name", file); r_cons_println (file); } break; case 'S': if (input[1] == ' ') { r_core_project_save_rdb (core, input + 2, R_CORE_PRJ_ALL); } else { eprintf ("Usage: PS [file]\n"); } break; case 'n': if (!fileproject || !*fileproject) { eprintf ("No project\n"); } else { switch (input[1]) { case '-': /* remove lines containing specific words */ { FILE *fd = r_sandbox_fopen (str, "w"); if (!fd) { eprintf ("Cannot open %s\n", str); } else { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); int del = 0; if (data) { char *ptr, *nl; for (ptr = data; ptr; ptr = nl) { nl = strchr (ptr, '\n'); if (nl) { *nl++ = 0; if (strstr (ptr, input + 2)) { del++; } else { fprintf (fd, "%s\n", ptr); } } } free (data); } if (del > 0) { eprintf ("Deleted %d lines\n", del); } free (str); fclose (fd); } } break; case ' ': if (input[2] == '-') { char *str = r_core_project_notes_file (core, fileproject); // edit with cfg.editor const char *editor = r_config_get (core->config, "cfg.editor"); if (str && *str && editor && *editor) { r_sys_cmdf ("%s %s", editor, str); } else { eprintf ("No cfg.editor configured\n"); } free (str); } else { //char *str = r_core_project_notes_file (core, fileproject); // append line to project notes char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "a"); if (fd) { fprintf (fd, "%s\n", input + 2); fclose (fd); } free (str); free (data); } break; case 'j': if (!input[2]) { int len = 0; /* get base64 string */ char *str = r_core_project_notes_file (core, fileproject); if (str) { char *data = r_file_slurp (str, &len); char *res = r_base64_encode_dyn (data, len); if (res) { r_cons_println (res); free (res); } free (data); free (str); } } else if (input[2] == ' ') { /* set base64 string */ ut8 *data = r_base64_decode_dyn (input + 3, -1); if (data) { char *str = r_core_project_notes_file (core, fileproject); if (str) { r_file_dump (str, data, strlen ((const char *) data), 0); free (str); } free (data); } } else { eprintf ("Usage: `Pnj` or `Pnj ...`\n"); } break; case 'x': r_core_project_execute_cmds (core, fileproject); break; case 0: { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); if (data) { r_cons_println (data); free (data); } free (str); } break; case '?': { const char *help_msg[] = { "Usage:", "Pn[j-?] [...]", "Project Notes", "Pn", "", "show project notes", "Pn", " -", "edit notes with cfg.editor", "Pn-", "", "delete notes", "Pn-", "str", "delete lines matching /str/ in notes", "Pnx", "", "run project note commands", "Pnj", "", "show notes in base64", "Pnj", " [base64]", "set notes in base64", NULL }; r_core_cmd_help (core, help_msg); } break; } } break; case 'i': if (file && *file) { char *prjName = r_core_project_info (core, file); r_cons_println (prjName); free (prjName); } break; default: { const char *help_msg[] = { "Usage:", "P[?osi] [file]", "Project management", "Pc", " [file]", "show project script to console", "Pd", " [file]", "delete project", "Pi", " [file]", "show project information", "Pl", "", "list all projects", "Pn", "[j]", "show project notes (Pnj for json)", "Pn", " [base64]", "set notes text", "Pn", " -", "edit notes with cfg.editor", "Po", " [file]", "open project", "Ps", " [file]", "save project", "PS", " [file]", "save script file", "P-", " [file]", "delete project (alias for Pd)", "NOTE:", "", "See 'e??prj.'", "NOTE:", "", "project are stored in ~/.config/radare2/projects", NULL }; r_core_cmd_help (core, help_msg); } break; } free (str); return true; }
static int rafind_open_file(char *file) { const char *kw; RListIter *iter; bool last = false; int ret; if (!quiet) { printf ("File: %s\n", file); } if (identify) { char *cmd = r_str_newf ("r2 -e search.show=false -e search.maxhits=1 -nqcpm '%s'", file); r_sandbox_system (cmd, 1); free (cmd); return 0; } io = r_io_new (); fd = r_io_open_nomap (io, file, R_PERM_R, 0); if (!fd) { eprintf ("Cannot open file '%s'\n", file); return 1; } r_cons_new (); rs = r_search_new (mode); if (!rs) { return 1; } buf = calloc (1, bsize); if (!buf) { eprintf ("Cannot allocate %"PFMT64d" bytes\n", bsize); return 1; } rs->align = align; r_search_set_callback (rs, &hit, buf); if (to == -1) { to = r_io_size(io); } if (mode == R_SEARCH_STRING) { /* TODO: implement using api */ r_sys_cmdf ("rabin2 -qzzz '%s'", file); return 0; } if (mode == R_SEARCH_MAGIC) { char *tostr = (to && to != UT64_MAX)? r_str_newf ("-e search.to=%"PFMT64d, to): strdup (""); char *cmd = r_str_newf ("r2" " -e search.in=range" " -e search.align=%d" " -e search.from=%"PFMT64d " %s -qnc/m '%s'", align, from, tostr, file); r_sandbox_system (cmd, 1); free (cmd); free (tostr); return 0; } if (mode == R_SEARCH_ESIL) { char *cmd; r_list_foreach (keywords, iter, kw) { cmd = r_str_newf ("r2 -qc \"/E %s\" %s", kw, file); r_sandbox_system (cmd, 1); free (cmd); }
static int cmd_project(void *data, const char *input) { RCore *core = (RCore *)data; const char *file, *arg = input+1; const char *fileproject = r_config_get (core->config, "file.project"); char *str = strdup (fileproject); if (*arg==' ') arg++; file = input[1]?arg:str; switch (input[0]) { case 'c': if (!input[1]) { eprintf ("TODO: Show project saving script to console\n"); } else if (input[1]==' ') { r_core_project_cat (core, input+2); } else eprintf ("Usage: Pc [prjname]\n"); break; case 'o': // if (r_file_is_regular (file)) if (input[1]) { r_core_project_open (core, file); } else { if (file && *file) r_cons_printf ("%s\n", file); } break; case 'l': r_core_project_list (core, input[1]); break; case 'd': r_core_project_delete (core, file); break; case 's': if (r_core_project_save (core, file)) { r_config_set (core->config, "file.project", file); r_cons_printf ("%s\n", file); } break; case 'n': if (!fileproject || !*fileproject) { eprintf ("No project\n"); } else switch (input[1]) { case '-': /* remove lines containing specific words */ { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "w"); if (!fd) { eprintf ("Cannot open %s\n", str); } else { int del = 0; if (data) { char *ptr, *nl; for (ptr = data; ptr; ptr = nl) { nl = strchr (ptr, '\n'); if (nl) { *nl++ = 0; if (strstr (ptr, input+2)) { del ++; } else { fprintf (fd, "%s\n", ptr); } } } free (data); } fclose (fd); free (str); if (del>0) { eprintf ("Deleted %d lines\n", del); } } } break; case ' ': if (input[2]=='-') { char *str = r_core_project_notes_file (core, fileproject); // edit with cfg.editor const char *editor = r_config_get (core->config, "cfg.editor"); if (str && *str && editor && *editor) r_sys_cmdf ("%s %s", editor, str); else eprintf ("No cfg.editor configured\n"); free (str); } else { //char *str = r_core_project_notes_file (core, fileproject); // append line to project notes char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); FILE *fd = r_sandbox_fopen (str, "a"); if (fd) { fprintf (fd, "%s\n", input+2); fclose (fd); } free (str); free (data); } break; case 'j': if (!input[2]) { int len = 0; /* get base64 string */ char *str = r_core_project_notes_file (core, fileproject); if (str) { char *data = r_file_slurp (str, &len); char *res = r_base64_encode_dyn (data, len); if (res) { r_cons_printf ("%s\n", res); free (res); } free (data); free (str); } } else if (input[2] == ' ') { /* set base64 string */ ut8 *data = r_base64_decode_dyn (input+3, 0); if (data) { char *str = r_core_project_notes_file (core, fileproject); if (str) { r_file_dump (str, data, strlen ((const char*)data)); free (str); } free (data); } } else { eprintf ("Usage: `Pnj` or `Pnj ...`\n"); } break; case 0: { char *str = r_core_project_notes_file (core, fileproject); char *data = r_file_slurp (str, NULL); if (data) { r_cons_printf ("%s\n", data); free (data); } free (str); } break; case '?': { const char* help_msg[] = { "Usage:", "Pn[j-?] [...]", "Project Notes", "Pn", "", "show project notes", "Pn", " -", "edit notes with cfg.editor", "Pn-", "", "delete notes", "Pn-", "str", "delete lines matching /str/ in notes", "Pnj", "", "show notes in base64", "Pnj", " [base64]", "set notes in base64", NULL}; r_core_cmd_help (core, help_msg); } break; } break; case 'i': // if (r_file_is_regular (file)) free (r_core_project_info (core, file)); break; default: { const char* help_msg[] = { "Usage:", "P[?osi] [file]", "Project management", "Pc", "", "show what will be saved in the project script", "Pc", " [file]", "show project script to console", "Pd", " [file]", "delete project", "Pi", " [file]", "show project information", "Pl", "", "list all projects", "Pn", "[j]", "show project notes (Pnj for json)", "Pn", " [base64]", "set notes text", "Pn", " -", "edit notes with cfg.editor", "Po", " [file]", "open project", "Ps", " [file]", "save project", "NOTE:", "", "See 'e file.project'", "NOTE:", "", "project files are stored in ~/.config/radare2/projects", NULL}; r_core_cmd_help (core, help_msg); } break; } free (str); return R_TRUE; }