R_API int r_core_project_delete(RCore *core, const char *prjfile) { if (r_sandbox_enable (0)) { eprintf ("Cannot delete project in sandbox mode\n"); return 0; } char *path = projectScriptPath (core, prjfile); if (!path) { eprintf ("Invalid project name '%s'\n", prjfile); return false; } if (r_core_is_project (core, prjfile)) { char *prjDir = r_file_dirname (path); if (!prjDir) { eprintf ("Cannot resolve directory\n"); free (path); return false; } // rm project file if (r_file_exists (path)) { r_file_rm (path); eprintf ("rm %s\n", path); } //rm notes.txt file char *notes_txt = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "notes.txt"); if (r_file_exists (notes_txt)) { r_file_rm (notes_txt); eprintf ("rm %s\n", notes_txt); } free(notes_txt); char *rop_d = r_str_newf ("%s%s%s", prjDir, R_SYS_DIR, "rop.d"); if (r_file_is_directory (rop_d)) { char *f; RListIter *iter; RList *files = r_sys_dir (rop_d); r_list_foreach (files, iter, f) { char *filepath = r_str_append (strdup (rop_d), R_SYS_DIR); filepath = r_str_append (filepath, f); if (!r_file_is_directory (filepath)) { eprintf ("rm %s\n", filepath); r_file_rm (filepath); } free (filepath); } r_file_rm (rop_d); eprintf ("rm %s\n", rop_d); r_list_free (files); } free (rop_d); // remove directory only if it's empty r_file_rm (prjDir); free (prjDir); }
// XXX: temporary files are R_API int r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) { if (r_mem_is_printable (a, R_MIN (5, la))) { r_file_dump (".a", a, la, 0); r_file_dump (".b", b, lb, 0); } else { r_file_hexdump (".a", a, la, 0); r_file_hexdump (".b", b, lb, 0); } r_sys_cmd ("diff -ru .a .b"); r_file_rm (".a"); r_file_rm (".b"); return 0; }
static char *r_debug_rap_reg_profile(RDebug *dbg) { char *out, *tf = r_file_temp ("/tmp/rap.XXXXXX"); int fd = r_cons_pipe_open (tf, 1, 0); r_io_system (dbg->iob.io, "drp"); r_cons_pipe_close (fd); out = r_file_slurp (tf, NULL); r_file_rm (tf); return out; }
static int r_vala_file(RLang *lang, const char *file) { void *lib; char *p, name[512], buf[512]; char *vapidir; if (!strstr (file, ".vala")) sprintf (name, "%s.vala", file); else strcpy (name, file); if (!r_file_exists (name)) { eprintf ("file not found (%s)\n", name); return R_FALSE; } vapidir = r_sys_getenv ("VAPIDIR"); if (vapidir) { if (*vapidir) { snprintf (buf, sizeof (buf), "valac --vapidir=%s --pkg r_core -C %s", vapidir, name); } free (vapidir); } else sprintf (buf, "valac --pkg r_core -C %s", name); if (system (buf) != 0) return R_FALSE; p = strstr (name, ".vala"); if (p) *p=0; p = strstr (name, ".gs"); if (p) *p=0; snprintf (buf, sizeof (buf), "gcc -fPIC -shared %s.c -o lib%s."R_LIB_EXT " $(pkg-config --cflags --libs r_core gobject-2.0)", name, name); if (system (buf) != 0) return R_FALSE; snprintf (buf, sizeof (buf), "./lib%s."R_LIB_EXT, name); lib = r_lib_dl_open (buf); if (lib!= NULL) { void (*fcn)(RCore *); fcn = r_lib_dl_sym (lib, "entry"); if (fcn) fcn (lang->user); else eprintf ("Cannot find 'entry' symbol in library\n"); r_lib_dl_close (lib); } else eprintf ("Cannot open library\n"); r_file_rm (buf); // remove lib sprintf (buf, "%s.c", name); // remove .c r_file_rm (buf); return 0; }
// XXX: temporary files are R_API char *r_diff_buffers_unified(RDiff *d, const ut8 *a, int la, const ut8 *b, int lb) { r_file_dump (".a", a, la, 0); r_file_dump (".b", b, lb, 0); #if 0 if (r_mem_is_printable (a, R_MIN (5, la))) { r_file_dump (".a", a, la, 0); r_file_dump (".b", b, lb, 0); } else { r_file_hexdump (".a", a, la, 0); r_file_hexdump (".b", b, lb, 0); } #endif char* err = NULL; char* out = NULL; int out_len; (void)r_sys_cmd_str_full ("/usr/bin/diff -u .a .b", NULL, &out, &out_len, &err); r_file_rm (".a"); r_file_rm (".b"); free (err); return out; }
static int lang_c_run(RLang *lang, const char *code, int len) { FILE *fd = fopen (".tmp.c", "w"); if (fd) { fputs ("#include <r_core.h>\n\nvoid entry(RCore *core) {\n", fd); fputs (code, fd); fputs ("\n}\n", fd); fclose (fd); lang_c_file (lang, ".tmp.c"); r_file_rm (".tmp.c"); } else eprintf ("Cannot open .tmp.c\n"); return R_TRUE; }
static int vala_run(RLang *lang, const char *code, int len) { FILE *fd = fopen (".tmp.vala", "w"); if (fd) { fputs ("using Radare;\n\npublic static void entry(RCore core) {\n", fd); fputs (code, fd); fputs (";\n}\n", fd); fclose (fd); r_vala_file (lang, ".tmp.vala"); r_file_rm (".tmp.vala"); } else eprintf ("Cannot open .tmp.vala\n"); return R_TRUE; }
static int lang_c_file(RLang *lang, const char *file) { void *lib; char *cc, *p, name[512], buf[512]; const char *libpath, *libname; if (strlen (file) > (sizeof(name)-10)) return R_FALSE; if (!strstr (file, ".c")) sprintf (name, "%s.c", file); else strcpy (name, file); if (!r_file_exists (name)) { eprintf ("file not found (%s)\n", name); return R_FALSE; } { char *a = (char*)r_str_lchr (name, '/'); if (a) { *a = 0; libpath = name; libname = a+1; } else { libpath = "."; libname = name; } } p = strstr (name, ".c"); if (p) *p=0; cc = r_sys_getenv ("CC"); if (!cc || !*cc) cc = strdup ("gcc"); snprintf (buf, sizeof (buf), "%s -fPIC -shared %s -o %s/lib%s."R_LIB_EXT " $(pkg-config --cflags --libs r_core)", cc, file, libpath, libname); free (cc); if (r_sandbox_system (buf, 1) != 0) return R_FALSE; snprintf (buf, sizeof (buf), "%s/lib%s."R_LIB_EXT, libpath, libname); lib = r_lib_dl_open (buf); if (lib!= NULL) { void (*fcn)(RCore *); fcn = r_lib_dl_sym (lib, "entry"); if (fcn) fcn (lang->user); else eprintf ("Cannot find 'entry' symbol in library\n"); r_lib_dl_close (lib); } else eprintf ("Cannot open library\n"); r_file_rm (buf); // remove lib return 0; }
R_API int r_core_project_delete(RCore *core, const char *prjfile) { char *path; if (r_sandbox_enable (0)) { eprintf ("Cannot delete project in sandbox mode\n"); return 0; } path = r_core_project_file (core, prjfile); if (!path) { eprintf ("Invalid project name '%s'\n", prjfile); return false; } if (r_core_is_project (core, prjfile)) { // rm project file r_file_rm (path); eprintf ("rm %s\n", path); path = r_str_concat (path, ".d"); if (r_file_is_directory (path)) { char *f; RListIter *iter; RList *files = r_sys_dir (path); r_list_foreach (files, iter, f) { char *filepath = r_str_concat (strdup (path), R_SYS_DIR); filepath =r_str_concat (filepath, f); if (!r_file_is_directory (filepath)) { eprintf ("rm %s\n", filepath); r_file_rm (filepath); } free (filepath); } r_file_rm (path); eprintf ("rm %s\n", path); r_list_free (files); } // TODO: remove .d directory (BEWARE OF ROOT RIMRAFS!) // TODO: r_file_rmrf (path); }
static int lang_cpipe_run(RLang *lang, const char *code, int len) { FILE *fd = fopen (".tmp.c", "w"); if (fd) { eprintf ("Cannot open .tmp.c\n"); return false; } fputs ("#include <r_socket.h>\n\n" "#define R2P(x,y...) r2pipe_cmdf(r2p,x,##y)\n" "int main() {\n" " R2Pipe *r2p = r2pipe_open(NULL);", fd); fputs (code, fd); fputs ("\n}\n", fd); fclose (fd); lang_cpipe_file (lang, ".tmp.c"); r_file_rm (".tmp.c"); return true; }
static int lang_vala_run(RLang *lang, const char *code, int len) { bool silent = !strncmp (code, "-s", 2); FILE *fd = fopen (".tmp.vala", "w"); if (fd) { if (silent) { code += 2; } fputs ("using Radare;\n\npublic static void entry(RCore core) {\n", fd); fputs (code, fd); fputs (";\n}\n", fd); fclose (fd); lang_vala_file (lang, ".tmp.vala", silent); r_file_rm (".tmp.vala"); return true; } eprintf ("Cannot open .tmp.vala\n"); return false; }
static int lang_cpipe_file(RLang *lang, const char *file) { char *a, *cc, *p, name[512]; const char *libpath, *libname; if (strlen (file) > (sizeof (name)-10)) return false; if (!strstr (file, ".c")) sprintf (name, "%s.c", file); else strcpy (name, file); if (!r_file_exists (name)) { eprintf ("file not found (%s)\n", name); return false; } a = (char*)r_str_lchr (name, '/'); if (a) { *a = 0; libpath = name; libname = a + 1; } else { libpath = "."; libname = name; } r_sys_setenv ("PKG_CONFIG_PATH", R2_LIBDIR"/pkgconfig"); p = strstr (name, ".c"); if (p) *p = 0; cc = r_sys_getenv ("CC"); if (!cc || !*cc) { free (cc); cc = strdup ("gcc"); } char *buf = r_str_newf ("%s %s -o %s/bin%s" " $(pkg-config --cflags --libs r_socket)", cc, file, libpath, libname); free (cc); if (r_sandbox_system (buf, 1) == 0) { char *binfile = r_str_newf ("%s/bin%s", libpath, libname); lang_pipe_run (lang, binfile, -1); r_file_rm (binfile); free (binfile); } free (buf); return 0; }
static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) { char *expr = NULL; int i; RRunProfile *rp = r_run_new (NULL); if (!rp) { return NULL; } for (i = 0; argv[i]; i++) { rp->_args[i] = argv[i]; } rp->_args[i] = NULL; if (!argv[0]) { r_run_free (rp); return NULL; } rp->_program = strdup (argv[0]); rp->_dodebug = true; if (io->runprofile && *io->runprofile) { if (!r_run_parsefile (rp, io->runprofile)) { eprintf ("Can't find profile '%s'\n", io->runprofile); r_run_free (rp); return NULL; } if (strstr (io->runprofile, R_SYS_DIR ".rarun2.")) { (void)r_file_rm (io->runprofile); } } if (bits == 64) { r_run_parseline (rp, expr=strdup ("bits=64")); } else if (bits == 32) { r_run_parseline (rp, expr=strdup ("bits=32")); } free (expr); if (r_run_config_env (rp)) { eprintf ("Can't config the environment.\n"); r_run_free (rp); return NULL; } return rp; }
static void trace_me () { #if __APPLE__ signal (SIGTRAP, SIG_IGN); //NEED BY STEP #endif #if __APPLE__ || __BSD__ /* we can probably remove this #if..as long as PT_TRACE_ME is redefined for OSX in r_debug.h */ signal (SIGABRT, inferior_abort_handler); if (ptrace (PT_TRACE_ME, 0, 0, 0) != 0) { #else if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) != 0) { #endif r_sys_perror ("ptrace-traceme"); exit (MAGIC_EXIT); } } void handle_posix_error(int err) { switch (err) { case 0: // eprintf ("Success\n"); break; case 22: eprintf ("posix_spawnp: Invalid argument\n"); break; case 86: eprintf ("Unsupported architecture. Please specify -b 32\n"); break; default: eprintf ("posix_spawnp: unknown error %d\n", err); perror ("posix_spawnp"); break; } } static RRunProfile* _get_run_profile(RIO *io, int bits, char **argv) { char *expr = NULL; int i; RRunProfile *rp = r_run_new (NULL); if (!rp) { return NULL; } for (i = 0; argv[i]; i++) { rp->_args[i] = argv[i]; } rp->_args[i] = NULL; rp->_program = strdup (argv[0]); rp->_dodebug = true; if (io->runprofile && *io->runprofile) { if (!r_run_parsefile (rp, io->runprofile)) { eprintf ("Can't find profile '%s'\n", io->runprofile); r_run_free (rp); return NULL; } if (strstr (io->runprofile, R_SYS_DIR ".rarun2.")) { (void)r_file_rm (io->runprofile); } } if (bits == 64) { r_run_parseline (rp, expr=strdup ("bits=64")); } else if (bits == 32) { r_run_parseline (rp, expr=strdup ("bits=32")); } free (expr); if (r_run_config_env (rp)) { eprintf ("Can't config the environment.\n"); r_run_free (rp); return NULL; } return rp; }
/* TODO: simplify using r_write */ static int cmd_write(void *data, const char *input) { ut64 off; ut8 *buf; const char *arg; int wseek, i, size, len = strlen (input); char *tmp, *str, *ostr; RCore *core = (RCore *)data; #define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y) wseek = r_config_get_i (core->config, "cfg.wseek"); str = ostr = strdup (input+1); switch (*input) { case 'h': { char *p = strchr (input, ' '); if (p) { while (*p==' ') p++; p = r_file_path (p); if (p) { r_cons_printf ("%s\n", p); free (p); } } } break; case 'e': { ut64 addr = 0, len = 0, b_size = 0; st64 dist = 0; ut8* bytes = NULL; int cmd_suc = R_FALSE; char *input_shadow = NULL, *p = NULL; switch (input[1]) { case 'n': if (input[2] == ' ') { len = *input ? r_num_math (core->num, input+3) : 0; if (len > 0){ ut64 cur_off = core->offset; cmd_suc = r_core_extend_at (core, core->offset, len); core->offset = cur_off; r_core_block_read (core, 0); } } break; case 'N': if (input[2] == ' ') { input += 3; while (*input && *input == ' ') input++; addr = r_num_math (core->num, input); while (*input && *input != ' ') input++; input++; len = *input ? r_num_math (core->num, input) : 0; if (len > 0){ ut64 cur_off = core->offset; cmd_suc = r_core_extend_at (core, addr, len); cmd_suc = r_core_seek (core, cur_off, 1); core->offset = addr; r_core_block_read (core, 0); } } break; case 'x': if (input[2] == ' ') { input+=2; len = *input ? strlen (input) : 0; bytes = len > 1? malloc (len+1) : NULL; len = bytes ? r_hex_str2bin (input, bytes) : 0; if (len > 0) { ut64 cur_off = core->offset; cmd_suc = r_core_extend_at (core, cur_off, len); if (cmd_suc) { r_core_write_at (core, cur_off, bytes, len); } core->offset = cur_off; r_core_block_read (core, 0); } free (bytes); } break; case 'X': if (input[2] == ' ') { addr = r_num_math (core->num, input+3); input += 3; while (*input && *input != ' ') input++; input++; len = *input ? strlen (input) : 0; bytes = len > 1? malloc (len+1) : NULL; len = bytes ? r_hex_str2bin (input, bytes) : 0; if (len > 0) { //ut64 cur_off = core->offset; cmd_suc = r_core_extend_at (core, addr, len); if (cmd_suc) { r_core_write_at (core, addr, bytes, len); } core->offset = addr; r_core_block_read (core, 0); } free (bytes); } break; case 's': input += 3; while (*input && *input == ' ') input++; len = strlen (input); input_shadow = len > 0? malloc (len+1): 0; // since the distance can be negative, // the r_num_math will perform an unwanted operation // the solution is to tokenize the string :/ if (input_shadow) { strncpy (input_shadow, input, len+1); p = strtok (input_shadow, " "); addr = p && *p ? r_num_math (core->num, p) : 0; p = strtok (NULL, " "); dist = p && *p ? r_num_math (core->num, p) : 0; p = strtok (NULL, " "); b_size = p && *p ? r_num_math (core->num, p) : 0; if (dist != 0){ r_core_shift_block (core, addr, b_size, dist); r_core_seek (core, addr, 1); cmd_suc = R_TRUE; } } free (input_shadow); break; case '?': default: cmd_suc = R_FALSE; } if (cmd_suc == R_FALSE) { r_cons_printf ("|Usage: write extend\n" "wen <num> insert num null bytes at current offset\n" "wex <hex_bytes> insert bytes at current offset\n" "weN <addr> <len> insert bytes at address\n" "weX <addr> <hex_bytes> insert bytes at address\n" "wes <addr> <dist> <block_size> shift a blocksize left or write in the editor\n" ); } } break; case 'p': if (input[1]=='-' || (input[1]==' '&&input[2]=='-')) { const char *tmpfile = ".tmp"; char *out = r_core_editor (core, NULL); if (out) { // XXX hacky .. patch should support str, not only file r_file_dump (tmpfile, (ut8*)out, strlen (out)); r_core_patch (core, tmpfile); r_file_rm (tmpfile); free (out); } } else { if (input[1]==' ' && input[2]) { r_core_patch (core, input+2); } else { eprintf ("Usage: wp [-|r2patch-file]\n" "TODO: rapatch format documentation here\n"); } } break; case 'u': // TODO: implement it in an API RCore.write_unified_hexpatch() is ETOOLONG if (input[1]==' ') { char *data = r_file_slurp (input+2, NULL); if (data) { char sign = ' '; int line = 0, offs = 0, hexa = 0; int newline = 1; for (i=0; data[i]; i++) { switch (data[i]) { case '+': if (newline) sign = 1; break; case '-': if (newline) { sign = 0; offs = i + ((data[i+1]==' ')?2:1); } break; case ' ': data[i] = 0; if (sign) { if (!line) line = i+1; else if (!hexa) hexa = i+1; } break; case '\r': break; case '\n': newline = 1; if (sign == -1) { offs = 0; line = 0; hexa = 0; } else if (sign) { if (offs && hexa) { r_cons_printf ("wx %s @ %s\n", data+hexa, data+offs); } else eprintf ("food\n"); offs = 0; line = 0; } else hexa = 0; sign = -1; continue; } newline = 0; } free (data); } } else { eprintf ("|Usage: wu [unified-diff-patch] # see 'cu'\n"); } break; case 'r': off = r_num_math (core->num, input+1); len = (int)off; if (len>0) { buf = malloc (len); if (buf != NULL) { r_num_irand (); for (i=0; i<len; i++) buf[i] = r_num_rand (256); r_core_write_at (core, core->offset, buf, len); WSEEK (core, len); free (buf); } else eprintf ("Cannot allocate %d bytes\n", len); } break; case 'A': switch (input[1]) { case ' ': if (input[2] && input[3]==' ') { r_asm_set_pc (core->assembler, core->offset); eprintf ("modify (%c)=%s\n", input[2], input+4); len = r_asm_modify (core->assembler, core->block, input[2], r_num_math (core->num, input+4)); eprintf ("len=%d\n", len); if (len>0) { r_core_write_at (core, core->offset, core->block, len); WSEEK (core, len); } else eprintf ("r_asm_modify = %d\n", len); } else eprintf ("Usage: wA [type] [value]\n"); break; case '?': default: r_cons_printf ("|Usage: wA [type] [value]\n" "|Types:\n" "| r raw write value\n" "| v set value (taking care of current address)\n" "| d destination register\n" "| 0 1st src register\n" "| 1 2nd src register\n" "|Example: wA r 0 # e800000000\n"); break; } break; case 'c': switch (input[1]) { case 'i': r_io_cache_commit (core->io); r_core_block_read (core, 0); break; case 'r': r_io_cache_reset (core->io, R_TRUE); /* Before loading the core block we have to make sure that if * the cache wrote past the original EOF these changes are no * longer displayed. */ memset (core->block, 0xff, core->blocksize); r_core_block_read (core, 0); break; case '-': if (input[2]=='*') { r_io_cache_reset (core->io, R_TRUE); } else if (input[2]==' ') { char *p = strchr (input+3, ' '); ut64 to, from = core->offset; if (p) { *p = 0; from = r_num_math (core->num, input+3); to = r_num_math (core->num, input+3); if (to<from) { eprintf ("Invalid range (from>to)\n"); return 0; } } else { from = r_num_math (core->num, input+3); to = from + core->blocksize; } r_io_cache_invalidate (core->io, from, to); } else { eprintf ("Invalidate write cache at 0x%08"PFMT64x"\n", core->offset); r_io_cache_invalidate (core->io, core->offset, core->offset+core->blocksize); } /* See 'r' above. */ memset (core->block, 0xff, core->blocksize); r_core_block_read (core, 0); break; case '?': r_cons_printf ( "|Usage: wc[ir*?]\n" "| wc list all write changes\n" "| wc- [a] [b] remove write op at curseek or given addr\n" "| wc* \"\" in radare commands\n" "| wcr reset all write changes in cache\n" "| wci commit write cache\n" "|NOTE: Requires 'e io.cache=true'\n"); break; case '*': r_io_cache_list (core->io, R_TRUE); break; case '\0': if (!r_config_get_i (core->config, "io.cache")) eprintf ("[warning] e io.cache must be true\n"); r_io_cache_list (core->io, R_FALSE); break; } break; case ' ': /* write string */ len = r_str_unescape (str); r_core_write_at (core, core->offset, (const ut8*)str, len); #if 0 r_io_use_desc (core->io, core->file->desc); r_io_write_at (core->io, core->offset, (const ut8*)str, len); #endif WSEEK (core, len); r_core_block_read (core, 0); break; case 't': if (*str != ' ') { eprintf ("Usage: wt file [size]\n"); } else { tmp = strchr (str+1, ' '); if (tmp) { st64 sz = (st64) r_num_math (core->num, tmp+1); *tmp = 0; if (sz<1) eprintf ("Invalid length\n"); else r_core_dump (core, str+1, core->offset, (ut64)sz); } else r_file_dump (str+1, core->block, core->blocksize); } break; case 'T': eprintf ("TODO: wT // why?\n"); break; case 'f': arg = (const char *)(input+((input[1]==' ')?2:1)); if (!strcmp (arg, "-")) { char *out = r_core_editor (core, NULL); if (out) { r_io_write_at (core->io, core->offset, (ut8*)out, strlen (out)); free (out); } } else if ((buf = (ut8*) r_file_slurp (arg, &size))) { r_io_use_desc (core->io, core->file->desc); r_io_write_at (core->io, core->offset, buf, size); WSEEK (core, size); free (buf); r_core_block_read (core, 0); } else eprintf ("Cannot open file '%s'\n", arg); break; case 'F': arg = (const char *)(input+((input[1]==' ')?2:1)); if (!strcmp (arg, "-")) { int len; ut8 *out; char *in = r_core_editor (core, NULL); if (in) { out = (ut8 *)strdup (in); if (out) { len = r_hex_str2bin (in, out); if (len>0) r_io_write_at (core->io, core->offset, out, len); free (out); } free (in); } } else if ((buf = r_file_slurp_hexpairs (arg, &size))) { r_io_use_desc (core->io, core->file->desc); r_io_write_at (core->io, core->offset, buf, size); WSEEK (core, size); free (buf); r_core_block_read (core, 0); } else eprintf ("Cannot open file '%s'\n", arg); break; case 'w': str++; len = (len-1)<<1; if (len>0) tmp = malloc (len+1); else tmp = NULL; if (tmp) { for (i=0; i<len; i++) { if (i%2) tmp[i] = 0; else tmp[i] = str[i>>1]; } str = tmp; r_io_use_desc (core->io, core->file->desc); r_io_write_at (core->io, core->offset, (const ut8*)str, len); WSEEK (core, len); r_core_block_read (core, 0); free (tmp); } else eprintf ("Cannot malloc %d\n", len); break; case 'x': { int b, len = strlen (input); ut8 *buf = malloc (len+1); len = r_hex_str2bin (input+1, buf); if (len != 0) { if (len<0) len = -len+1; if (len<core->blocksize) { b = core->block[len]&0xf; b |= (buf[len]&0xf0); } else b = buf[len]; buf[len] = b; r_core_write_at (core, core->offset, buf, len); WSEEK (core, len); r_core_block_read (core, 0); } else eprintf ("Error: invalid hexpair string\n"); free (buf); } break; case 'a': switch (input[1]) { case 'o': if (input[2] == ' ') r_core_hack (core, input+3); else r_core_hack_help (core); break; case ' ': case '*': { const char *file = input[1]=='*'? input+2: input+1; RAsmCode *acode; r_asm_set_pc (core->assembler, core->offset); acode = r_asm_massemble (core->assembler, file); if (acode) { if (input[1]=='*') { r_cons_printf ("wx %s\n", acode->buf_hex); } else { if (r_config_get_i (core->config, "scr.prompt")) eprintf ("Written %d bytes (%s) = wx %s\n", acode->len, input+2, acode->buf_hex); r_core_write_at (core, core->offset, acode->buf, acode->len); WSEEK (core, acode->len); r_core_block_read (core, 0); } r_asm_code_free (acode); } } break; case 'f': if ((input[2]==' '||input[2]=='*')) { const char *file = input[2]=='*'? input+4: input+3; RAsmCode *acode; r_asm_set_pc (core->assembler, core->offset); acode = r_asm_assemble_file (core->assembler, file); if (acode) { if (input[2]=='*') { r_cons_printf ("wx %s\n", acode->buf_hex); } else { if (r_config_get_i (core->config, "scr.prompt")) eprintf ("Written %d bytes (%s)=wx %s\n", acode->len, input+1, acode->buf_hex); r_core_write_at (core, core->offset, acode->buf, acode->len); WSEEK (core, acode->len); r_core_block_read (core, 0); } r_asm_code_free (acode); } else eprintf ("Cannot assemble file\n"); } else eprintf ("Wrong argument\n"); break; default: r_cons_printf ("|Usage: wa[of*] [arg]\n" "| wa nop : write nopcode using asm.arch and asm.bits\n" "| wa* mov eax, 33 : show 'wx' op with hexpair bytes of sassembled opcode\n" "| \"wa nop;nop\" : assemble more than one instruction (note the quotes)\n" "| waf foo.asm : assemble file and write bytes\n" "| wao nop : convert current opcode into nops\n" "| wao? : show help for assembler operation on current opcode (hack)\n"); break; } break; case 'b': { int len = strlen (input); ut8 *buf = malloc (len+1); if (buf) { len = r_hex_str2bin (input+1, buf); if (len > 0) { r_mem_copyloop (core->block, buf, core->blocksize, len); r_core_write_at (core, core->offset, core->block, core->blocksize); WSEEK (core, core->blocksize); r_core_block_read (core, 0); } else eprintf ("Wrong argument\n"); free (buf); } else eprintf ("Cannot malloc %d\n", len+1); } break; case 'm': size = r_hex_str2bin (input+1, (ut8*)str); switch (input[1]) { case '\0': eprintf ("Current write mask: TODO\n"); // TODO break; case '?': break; case '-': r_io_set_write_mask (core->io, 0, 0); eprintf ("Write mask disabled\n"); break; case ' ': if (size>0) { r_io_use_desc (core->io, core->file->desc); r_io_set_write_mask (core->io, (const ut8*)str, size); WSEEK (core, size); eprintf ("Write mask set to '"); for (i=0; i<size; i++) eprintf ("%02x", str[i]); eprintf ("'\n"); } else eprintf ("Invalid string\n"); break; } break; case 'v': { int type = 0; ut8 addr1; ut16 addr2; ut32 addr4, addr4_; ut64 addr8; switch (input[1]) { case '?': r_cons_printf ("|Usage: wv[size] [value] # write value of given size\n" "| wv1 234 # write one byte with this value\n" "| wv 0x834002 # write dword with this value\n" "|Supported sizes are: 1, 2, 4, 8\n"); return 0; case '1': type = 1; break; case '2': type = 2; break; case '4': type = 4; break; case '8': type = 8; break; } off = r_num_math (core->num, input+2); r_io_use_desc (core->io, core->file->desc); r_io_seek (core->io, core->offset, R_IO_SEEK_SET); if (type == 0) type = (off&UT64_32U)? 8: 4; switch (type) { case 1: addr1 = (ut8)off; r_io_write (core->io, (const ut8 *)&addr1, 1); WSEEK (core, 1); break; case 2: addr2 = (ut16)off; r_io_write (core->io, (const ut8 *)&addr2, 2); WSEEK (core, 2); break; case 4: addr4_ = (ut32)off; //drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */ //endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */ memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too r_io_write (core->io, (const ut8 *)&addr4, 4); WSEEK (core, 4); break; case 8: /* 8 byte addr */ memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here // endian_memcpy((ut8*)&addr8, (ut8*)&off, 8); r_io_write (core->io, (const ut8 *)&addr8, 8); WSEEK (core, 8); break; } r_core_block_read (core, 0); } break; case 'o': switch (input[1]) { case 'a': case 's': case 'e': case 'A': case 'x': case 'r': case 'l': case 'm': case 'd': case 'o': case 'w': if (input[2]!=' ') { if (input[1]=='e') r_cons_printf ( "Usage: 'woe from-to step'\n"); else r_cons_printf ( "Usage: 'wo%c 00 11 22'\n", input[1]); free (ostr); return 0; } case '2': case '4': r_core_write_op (core, input+3, input[1]); r_core_block_read (core, 0); break; case 'R': r_core_cmd0 (core, "wr $b"); break; case 'n': r_core_write_op (core, "ff", 'x'); r_core_block_read (core, 0); break; case '\0': case '?': default: r_cons_printf ( "|Usage: wo[asmdxoArl24] [hexpairs] @ addr[:bsize]\n" "|Example:\n" "| wox 0x90 ; xor cur block with 0x90\n" "| wox 90 ; xor cur block with 0x90\n" "| wox 0x0203 ; xor cur block with 0203\n" "| woa 02 03 ; add [0203][0203][...] to curblk\n" "| woe 02 03 \n" "|Supported operations:\n" "| wow == write looped value (alias for 'wb')\n" "| woa += addition\n" "| wos -= substraction\n" "| wom *= multiply\n" "| wod /= divide\n" "| wox ^= xor\n" "| woo |= or\n" "| woA &= and\n" "| woR random bytes (alias for 'wr $b'\n" "| wor >>= shift right\n" "| wol <<= shift left\n" "| wo2 2= 2 byte endian swap\n" "| wo4 4= 4 byte endian swap\n" ); break; } break; case 'd': if (input[1]==' ') { char *arg, *inp = strdup (input+2); arg = strchr (inp, ' '); if (arg) { *arg = 0; ut64 addr = r_num_math (core->num, input+2); ut64 len = r_num_math (core->num, arg+1); ut8 *data = malloc (len); r_io_read_at (core->io, addr, data, len); r_io_write_at (core->io, core->offset, data, len); free (data); } else eprintf ("See wd?\n"); free (inp); } else eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n"); break; case 's': { ut8 ulen; len = r_str_unescape (str+1); if (len>255) { eprintf ("Too large\n"); } else { ulen = (ut8)len; r_core_write_at (core, core->offset, &ulen, 1); r_core_write_at (core, core->offset+1, (const ut8*)str+1, len); WSEEK (core, len); r_core_block_read (core, 0); } } break; default: case '?': if (core->oobi) { eprintf ("Writing oobi buffer!\n"); r_io_use_desc (core->io, core->file->desc); r_io_write (core->io, core->oobi, core->oobi_len); WSEEK (core, core->oobi_len); r_core_block_read (core, 0); } else r_cons_printf ( "|Usage: w[x] [str] [<file] [<<EOF] [@addr]\n" "| w foobar write string 'foobar'\n" "| wh r2 whereis/which shell command\n" "| wr 10 write 10 random bytes\n" "| ww foobar write wide string 'f\\x00o\\x00o\\x00b\\x00a\\x00r\\x00'\n" "| wa push ebp write opcode, separated by ';' (use '\"' around the command)\n" "| waf file assemble file and write bytes\n" "| wA r 0 alter/modify opcode at current seek (see wA?)\n" "| wb 010203 fill current block with cyclic hexpairs\n" "| wc[ir*?] write cache undo/commit/reset/list (io.cache)\n" "| wd [off] [n] duplicate N bytes from offset at current seek (memcpy) (see y?)\n" "| wx 9090 write two intel nops\n" "| wv eip+34 write 32-64 bit value\n" "| wo? hex write in block with operation. 'wo?' fmi\n" "| wm f0ff set binary mask hexpair to be used as cyclic write mask\n" "| ws pstring write 1 byte for length and then the string\n" "| wf -|file write contents of file at current offset\n" "| wF -|file write contents of hexpairs file here\n" "| wp -|file apply radare patch file. See wp? fmi\n" "| wt file [sz] write to file (from current seek, blocksize or sz bytes)\n" ); //TODO: add support for offset+seek // " wf file o s ; write contents of file from optional offset 'o' and size 's'.\n" break; }
R_API char* r_egg_Cfile_parser(const char *file, const char *arch, const char *os, int bits) { char *output = NULL; char *fileExt = NULL; // "file" with extension (.s, .text, ...) struct cEnv_t *cEnv = r_egg_Cfile_set_cEnv (arch, os, bits); if (!cEnv) { goto fail; } r_str_sanitize (cEnv->CC); //printf ("==> Compile\n"); printf ("'%s' %s -o '%s.tmp' -S -Os '%s'\n", cEnv->CC, cEnv->CFLAGS, file, file); output = r_sys_cmd_strf ("('%s' %s -o '%s.tmp' -S -Os '%s') 2>&1", cEnv->CC, cEnv->CFLAGS, file, file); if (output == NULL) { eprintf ("Compilation failed!\n"); goto fail; } printf ("%s", output); if (!(fileExt = r_str_newf ("%s.s", file))) { goto fail; } if (!r_file_dump (fileExt, (const ut8*) cEnv->SHDR, strlen (cEnv->SHDR), false)) { eprintf ("Error while opening %s.s\n", file); goto fail; } if (!r_egg_Cfile_parseCompiled (file)) { goto fail; } //printf ("==> Assemble\n"); printf ("'%s' %s -Os -o '%s.o' '%s.s'\n", cEnv->CC, cEnv->LDFLAGS, file, file); free (output); output = r_sys_cmd_strf ("'%s' %s -Os -o '%s.o' '%s.s'", cEnv->CC, cEnv->LDFLAGS, file, file); if (!output) { eprintf ("Assembly failed!\n"); goto fail; } printf ("%s", output); //printf ("==> Link\n"); printf ("rabin2 -o '%s.text' -O d/S/'%s' '%s.o'\n", file, cEnv->TEXT, file); free (output); output = r_sys_cmd_strf ("rabin2 -o '%s.text' -O d/S/'%s' '%s'.o", file, cEnv->TEXT, file); if (!output) { eprintf ("Linkage failed!\n"); goto fail; } free (fileExt); if (!(fileExt = r_str_newf ("%s.o", file))) { goto fail; } if (!r_file_exists (fileExt)) { eprintf ("Cannot find %s.o\n", file); goto fail; } free (fileExt); if (!(fileExt = r_str_newf ("%s.text", file))) { goto fail; } if (r_file_size (fileExt) == 0) { printf ("FALLBACK: Using objcopy instead of rabin2"); free (output); output = r_sys_cmd_strf ("'%s' -j .text -O binary '%s.o' '%s.text'", cEnv->OBJCOPY, file, file); if (!output) { eprintf ("objcopy failed!\n"); goto fail; } } size_t i; const char *extArray[] = {"bin", "tmp", "s", "o"}; for (i = 0; i < 4; i++) { free (fileExt); if (!(fileExt = r_str_newf ("%s.%s", file, extArray[i]))) { goto fail; } r_file_rm (fileExt); } free (fileExt); if ((fileExt = r_str_newf ("%s.text", file)) == NULL) { goto fail; } free (output); r_egg_Cfile_free_cEnv (cEnv); return fileExt; fail: free (fileExt); free (output); r_egg_Cfile_free_cEnv (cEnv); return NULL; }
static int lang_vala_file(RLang *lang, const char *file, bool silent) { void *lib; char *p, name[512], buf[512]; char *vapidir, *srcdir, *libname; if (strlen (file)>500) return false; if (!strstr (file, ".vala")) sprintf (name, "%s.vala", file); else strcpy (name, file); if (!r_file_exists (name)) { eprintf ("file not found (%s)\n", name); return false; } srcdir = strdup (file); p = (char*)r_str_lchr (srcdir, '/'); if (p) { *p = 0; libname = strdup (p+1); if (*file!='/') { strcpy (srcdir, "."); } } else { libname = strdup (file); strcpy (srcdir, "."); } r_sys_setenv ("PKG_CONFIG_PATH", R2_LIBDIR"/pkgconfig"); vapidir = r_sys_getenv ("VAPIDIR"); char *tail = silent? " > /dev/null 2>&1": ""; if (vapidir) { if (*vapidir) { snprintf (buf, sizeof (buf)-1, "valac -d %s --vapidir=%s --pkg r_core -C %s %s", srcdir, vapidir, name, tail); } free (vapidir); } else { snprintf (buf, sizeof (buf) - 1, "valac -d %s --pkg r_core -C %s %s", srcdir, name, tail); } free (srcdir); if (r_sandbox_system (buf, 1) != 0) { free (libname); return false; } p = strstr (name, ".vala"); if (p) *p=0; p = strstr (name, ".gs"); if (p) *p=0; // TODO: use CC environ if possible snprintf (buf, sizeof (buf), "gcc -fPIC -shared %s.c -o lib%s."R_LIB_EXT " $(pkg-config --cflags --libs r_core gobject-2.0)", name, libname); if (r_sandbox_system (buf, 1) != 0) { free (libname); return false; } snprintf (buf, sizeof (buf), "./lib%s."R_LIB_EXT, libname); free (libname); lib = r_lib_dl_open (buf); if (lib != NULL) { void (*fcn)(RCore *); fcn = r_lib_dl_sym (lib, "entry"); if (fcn) fcn (lang->user); else eprintf ("Cannot find 'entry' symbol in library\n"); r_lib_dl_close (lib); } else eprintf ("Cannot open library\n"); r_file_rm (buf); // remove lib sprintf (buf, "%s.c", name); // remove .c r_file_rm (buf); return 0; }
static int download(struct SPDBDownloader *pd) { SPDBDownloaderOpt *opt = pd->opt; char *curl_cmd = NULL; char *extractor_cmd = NULL; char *abspath_to_archive = NULL; char *archive_name = NULL; const char *basepath = "."; int res = 1, archive_name_len = 0; if (!opt->dbg_file || !*opt->dbg_file) { // no pdb debug file return 0; } if (!checkPrograms ()) return 0; // dbg_file len is > 0 archive_name_len = strlen (opt->dbg_file); archive_name = malloc (archive_name_len+1); memcpy (archive_name, opt->dbg_file, archive_name_len+1); archive_name[archive_name_len-1] = '_'; if (opt->path && *opt->path) basepath = opt->path; abspath_to_archive = r_str_newf ("%s%s%s", basepath, R_SYS_DIR, archive_name); curl_cmd = r_str_newf ("curl -sA \"%s\" \"%s/%s/%s/%s\" -o \"%s\"", opt->user_agent, opt->symbol_server, opt->dbg_file, opt->guid, archive_name, abspath_to_archive); #if __WINDOWS__ && !__CYGWIN__ { const char *cabextractor = "expand"; const char *format = "%s %s %s"; char *abspath_to_file = strdup (abspath_to_archive); int abspath_to_archive_len = archive_name_len + strlen (basepath) + 2; abspath_to_file[abspath_to_archive_len - 2] = 'b'; // extact_cmd -> %1 %2 %3 // %1 - 'expand' // %2 - absolute path to archive // %3 - absolute path to file that will be dearchive extractor_cmd = r_str_newf (format, cabextractor, abspath_to_archive, abspath_to_file); } #else const char *cabextractor = "cabextract"; const char *format = "%s -d \"%s\" \"%s\""; // cabextract -d %1 %2 // %1 - path to directory where to extract all files from cab arhcive // %2 - absolute path to cab archive extractor_cmd = r_str_newf (format, cabextractor, basepath, abspath_to_archive); #endif if (r_sys_cmd (curl_cmd) != 0) { eprintf("curl has not been finish with sucess\n"); res = 0; } if (res && (r_sys_cmd (extractor_cmd) != 0)) { eprintf ("cab extrach has not been finished with sucess\n"); res = 0; } r_file_rm (abspath_to_archive); R_FREE (archive_name); R_FREE (curl_cmd); R_FREE (extractor_cmd); R_FREE (abspath_to_archive); return res; }