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_core_dump(RCore *core, const char *file, ut64 addr, ut64 size) { ut64 i; ut8 *buf; int bs = core->blocksize; FILE *fd; r_sys_truncate (file, 0); fd = r_sandbox_fopen (file, "wb"); if (!fd) { eprintf ("Cannot open '%s' for writing\n", file); return R_FALSE; } buf = malloc (bs); r_cons_break (NULL, NULL); for (i=0; i<size; i+=bs) { if (r_cons_singleton ()->breaked) break; if ((i+bs)>size) bs = size-i; r_io_read_at (core->io, addr+i, buf, bs); if (fwrite (buf, bs, 1, fd) <1) { eprintf ("write error\n"); break; } } eprintf ("dumped 0x%"PFMT64x" bytes\n", i); r_cons_break_end (); fclose (fd); free (buf); return R_TRUE; }
static int r_debug_wind_wait (RDebug *dbg, int pid) { # define STATE_EXCEPTION 0x3030 kd_packet_t *pkt; kd_stc_64 *stc; int ret; r_cons_break (wstatic_debug_break, dbg); dbreak = 0; for (;;) { ret = wind_wait_packet (wctx, KD_PACKET_TYPE_STATE_CHANGE, &pkt); if (dbreak) { dbreak = 0; wind_break (wctx); continue; } if (ret != KD_E_OK || !pkt) break; stc = (kd_stc_64 *)pkt->data; // Handle exceptions only if (stc->state == STATE_EXCEPTION) { wind_set_cpu (wctx, stc->cpu); free (pkt); dbg->reason.type = R_DEBUG_REASON_INT; dbg->reason.addr = stc->pc; dbg->reason.tid = stc->kthread; dbg->reason.signum = stc->state; break; } else wind_continue (wctx); free(pkt); } // TODO : Set the faulty process as target return R_TRUE; }
R_API void r_anal_type_match(RCore *core, RAnalFunction *fcn) { bool esil_var[STATES_SIZE] = {false}; if (!core ) { return; } if (!r_anal_emul_init (core, esil_var) || !fcn ) { r_anal_emul_restore (core, esil_var); return; } const char *pc = r_reg_get_name (core->anal->reg, R_REG_NAME_PC); ut64 addr = fcn->addr; r_reg_setv (core->dbg->reg, pc, fcn->addr); r_debug_reg_sync (core->dbg, -1, true); r_cons_break (NULL, NULL); while (!r_cons_is_breaked ()) { RAnalOp *op = r_core_anal_op (core, addr); int loop_count = sdb_num_get ( core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), 0); if (loop_count > LOOP_MAX) { eprintf ("Unfortunately your evilly engineered %s function trapped my most innocent `aftm` in an infinite loop.\n", fcn->name); eprintf ("I kept trace log for you to review and find out how bad things were going to happen by yourself.\n"); eprintf ("You can view this log by `ate`. Meanwhile, I will train on how to behave with such behaviour without bothering you.\n"); return; } sdb_num_set (core->anal->esil->db_trace, sdb_fmt (-1, "0x%"PFMT64x".count", addr), loop_count + 1, 0); if (!op || op->type == R_ANAL_OP_TYPE_RET) { r_anal_emul_restore (core, esil_var); return; } if (op->type == R_ANAL_OP_TYPE_CALL) { RAnalFunction *fcn_call = r_anal_get_fcn_in (core->anal, op->jump, -1); //eprintf ("in the middle of %s\n", fcn_call->name); if (fcn_call) { type_match (core, addr, fcn_call->name); } else { eprintf ("Cannot find function at 0x%08"PFMT64x"\n", op->jump); } addr += op->size; r_anal_op_free (op); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); addr += stack_clean (core, addr, fcn); r_reg_setv (core->dbg->reg, pc, addr); r_debug_reg_sync (core->dbg, -1, true); r_anal_esil_set_pc (core->anal->esil, addr); continue; } else { r_core_esil_step (core, UT64_MAX, NULL); r_anal_op_free (op); } r_core_cmd0 (core, ".ar*"); addr = r_reg_getv (core->anal->reg, pc); } r_cons_break_end (); r_anal_emul_restore (core, esil_var); }
DWORD WINAPI ThreadFunction(LPVOID lpParam) { RLang * lang = lpParam; CHAR buf[PIPE_BUF_SIZE]; BOOL bSuccess = FALSE; int i, res = 0; DWORD dwRead, dwWritten; r_cons_break (NULL, NULL); res = ConnectNamedPipe (hPipeInOut, NULL); if (!res) { eprintf ("ConnectNamedPipe failed\n"); return FALSE; } do { if (r_cons_singleton ()->breaked) { TerminateProcess(hproc,0); break; } memset (buf, 0, PIPE_BUF_SIZE); bSuccess = ReadFile (hPipeInOut, buf, PIPE_BUF_SIZE, &dwRead, NULL); if (bStopThread) break; if (bSuccess && dwRead>0) { buf[sizeof (buf)-1] = 0; char *res = lang->cmd_str ((RCore*)lang->user, buf); if (res) { int res_len = strlen (res) + 1; for (i = 0; i < res_len; i++) { memset (buf, 0, PIPE_BUF_SIZE); dwWritten = 0; int writelen=res_len - i; int rc = WriteFile (hPipeInOut, res + i, writelen>PIPE_BUF_SIZE?PIPE_BUF_SIZE:writelen, &dwWritten, 0); if (bStopThread) { free (res); break; } if (!rc) { eprintf ("WriteFile: failed 0x%x\n", (int)GetLastError()); } if (dwWritten > 0) { i += dwWritten - 1; } else { /* send null termination // chop */ eprintf ("w32-lang-pipe: 0x%x\n", (ut32)GetLastError ()); //WriteFile (hPipeInOut, "", 1, &dwWritten, NULL); //break; } } free (res); } else { WriteFile (hPipeInOut, "", 1, &dwWritten, NULL); } } } while(!bStopThread); r_cons_break_end (); return TRUE; }
static int bin_dwarf(RCore *core, int mode) { RBinDwarfRow *row; RListIter *iter; RList *list = NULL; RBinFile *binfile = r_core_bin_cur (core); RBinPlugin * plugin = r_bin_file_cur_plugin (binfile); if (!binfile) return false; if (plugin && plugin->lines) { list = plugin->lines (binfile); } else if (core->bin) { // TODO: complete and speed-up support for dwarf if (r_config_get_i (core->config, "bin.dwarf")) { RBinDwarfDebugAbbrev *da = NULL; da = r_bin_dwarf_parse_abbrev (core->bin, mode); r_bin_dwarf_parse_info (da, core->bin, mode); r_bin_dwarf_parse_aranges (core->bin, mode); list = r_bin_dwarf_parse_line (core->bin, mode); r_bin_dwarf_free_debug_abbrev (da); free (da); } } if (!list) return false; r_cons_break (NULL, NULL); r_list_foreach (list, iter, row) { if (r_cons_singleton()->breaked) break; if (mode) { // TODO: use 'Cl' instead of CC const char *path = row->file; char *line = r_file_slurp_line (path, row->line-1, 0); if (line) { r_str_filter (line, strlen (line)); line = r_str_replace (line, "\"", "\\\"", 1); line = r_str_replace (line, "\\\\", "\\", 1); } // TODO: implement internal : if ((mode & R_CORE_BIN_SET)) if ((mode & R_CORE_BIN_SET)) { char *cmt = r_str_newf ("%s:%d %s", row->file, row->line, line?line:""); r_meta_set_string (core->anal, R_META_TYPE_COMMENT, row->address, cmt); free (cmt); } else { r_cons_printf ("\"CC %s:%d %s\"@0x%"PFMT64x"\n", row->file, row->line, line?line:"", row->address); } free (line); } else { r_cons_printf ("0x%08"PFMT64x"\t%s\t%d\n", row->address, row->file, row->line); } } r_cons_break_end (); r_list_free (list); return true; }
R_API int r_core_rtr_cmds (RCore *core, const char *port) { unsigned char buf[4097]; RSocket *ch, *s; int i, ret; char *str; if (!port || port[0]=='?') { r_cons_printf ("Usage: .:[tcp-port] run r2 commands for clients\n"); return R_FALSE; } s = r_socket_new (0); if (!r_socket_listen (s, port, NULL)) { eprintf ("Error listening on port %s\n", port); r_socket_free (s); return R_FALSE; } eprintf ("Listening for commands on port %s\n", port); listenport = port; for (;;) { r_cons_break ((RConsBreak)http_break, core); ch = r_socket_accept (s); buf[0] = 0; ret = r_socket_read (ch, buf, sizeof (buf) - 1); if (ret>0) { buf[ret] = 0; for (i=0; buf[i]; i++) if (buf[i] == '\n') buf[i] = buf[i+1]? ';': '\0'; if (!r_config_get_i (core->config, "scr.prompt") \ && !strcmp ((char*)buf, "q!")) break; str = r_core_cmd_str (core, (const char *)buf); if (str &&*str) { r_socket_write (ch, str, strlen (str)); } else r_socket_write (ch, "\n", 1); free (str); } if (r_cons_singleton()->breaked) break; r_socket_close (ch); r_cons_break_end (); } r_socket_free(s); r_socket_free(ch); return 0; }
R_API ut64 r_debug_esil_step(RDebug *dbg, ut32 count) { count++; has_match = 0; r_cons_break (NULL, NULL); do { if (r_cons_is_breaked ()) break; if (has_match) { eprintf ("EsilBreak match at 0x%08"PFMT64x"\n", opc); break; } if (count>0) { count--; if (!count) { //eprintf ("Limit reached\n"); break; } } } while (r_debug_esil_stepi (dbg)); r_cons_break_end (); return opc; }
// TODO: add support for byte-per-byte opcode search R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to, int maxhits, int regexp) { RCoreAsmHit *hit; RAsmOp op; RList *hits; ut64 at, toff = core->offset; ut8 *buf; int align = core->search->align; RRegex* rx = NULL; char *tok, *tokens[1024], *code = NULL, *ptr; int idx, tidx = 0, ret, len; int tokcount, matchcount, count = 0; int matches = 0; if (!*input) return NULL; if (core->blocksize <= OPSZ) { eprintf ("error: block size too small\n"); return NULL; } if (!(buf = (ut8 *)calloc (core->blocksize, 1))) return NULL; if (!(ptr = strdup (input))) { free (buf); return NULL; } if (!(hits = r_core_asm_hit_list_new ())) { free (buf); free (ptr); return NULL; } tokens[0] = NULL; for (tokcount=0; tokcount<(sizeof (tokens) / sizeof (char*)) - 1; tokcount++) { tok = strtok (tokcount? NULL: ptr, ";"); if (!tok) break; tokens[tokcount] = r_str_trim_head_tail (tok); } tokens[tokcount] = NULL; r_cons_break (NULL, NULL); for (at = from, matchcount = 0; at < to; at += core->blocksize-OPSZ) { matches = 0; if (r_cons_singleton ()->breaked) break; ret = r_io_read_at (core->io, at, buf, core->blocksize); if (ret != core->blocksize) break; idx = 0, matchcount = 0; while (idx < core->blocksize) { ut64 addr = at + idx; r_asm_set_pc (core->assembler, addr); op.buf_asm[0] = 0; op.buf_hex[0] = 0; if (!(len = r_asm_disassemble (core->assembler, &op, buf+idx, core->blocksize-idx))) { idx = (matchcount)? tidx+1: idx+1; matchcount = 0; continue; } matches = true; if (!strcmp (op.buf_asm, "unaligned")) matches = false; if (!strcmp (op.buf_asm, "invalid")) matches = false; if (matches && tokens[matchcount]) { if (!regexp) matches = strstr(op.buf_asm, tokens[matchcount]) != NULL; else { rx = r_regex_new (tokens[matchcount], ""); matches = r_regex_exec (rx, op.buf_asm, 0, 0, 0) == 0; r_regex_free (rx); } } if (align && align>1) { if (addr % align) { matches = false; } } if (matches) { code = r_str_concatf (code, "%s; ", op.buf_asm); if (matchcount == tokcount-1) { if (tokcount == 1) tidx = idx; if (!(hit = r_core_asm_hit_new ())) { r_list_purge (hits); free (hits); hits = NULL; goto beach; } hit->addr = addr; hit->len = idx + len - tidx; if (hit->len == -1) { r_core_asm_hit_free (hit); goto beach; } code[strlen (code)-2] = 0; hit->code = strdup (code); r_list_append (hits, hit); R_FREE (code); matchcount = 0; idx = tidx+1; if (maxhits) { count ++; if (count >= maxhits) { //eprintf ("Error: search.maxhits reached\n"); goto beach; } } } else if (matchcount == 0) { tidx = idx; matchcount++; idx += len; } else { matchcount++; idx += len; } } else { idx = matchcount? tidx+1: idx+1; R_FREE (code); matchcount = 0; } } at += OPSZ; } r_asm_set_pc (core->assembler, toff); beach: free (buf); free (ptr); free (code); return hits; }
static int lang_pipe_run(RLang *lang, const char *code, int len) { #if __UNIX__ int safe_in = dup (0); int child, ret; int input[2]; int output[2]; pipe (input); pipe (output); env ("R2PIPE_IN", input[0]); env ("R2PIPE_OUT", output[1]); child = r_sys_fork (); if (child == -1) { /* error */ } else if (child == 0) { /* children */ r_sandbox_system (code, 1); write (input[1], "", 1); close (input[0]); close (input[1]); close (output[0]); close (output[1]); exit (0); return false; } else { /* parent */ char *res, buf[1024]; /* Close pipe ends not required in the parent */ close (output[1]); close (input[0]); r_cons_break (NULL, NULL); for (;;) { if (r_cons_singleton ()->breaked) { break; } memset (buf, 0, sizeof (buf)); ret = read (output[0], buf, sizeof (buf)-1); if (ret <1 || !buf[0]) { break; } buf[sizeof (buf)-1] = 0; res = lang->cmd_str ((RCore*)lang->user, buf); //eprintf ("%d %s\n", ret, buf); if (res) { write (input[1], res, strlen (res)+1); free (res); } else { eprintf ("r_lang_pipe: NULL reply for (%s)\n", buf); write (input[1], "", 1); // NULL byte } } /* workaround to avoid stdin closed */ if (safe_in != -1) close (safe_in); safe_in = open (ttyname(0), O_RDONLY); if (safe_in != -1) { dup2 (safe_in, 0); } else eprintf ("Cannot open ttyname(0) %s\n", ttyname(0)); r_cons_break_end (); } close (input[0]); close (input[1]); close (output[0]); close (output[1]); if (safe_in != -1) close (safe_in); waitpid (child, NULL, 0); return true; #else #if __WINDOWS__ HANDLE hThread = 0; char buf[512]; sprintf(buf,"R2PIPE_IN%x",_getpid()); SetEnvironmentVariable("R2PIPE_PATH",buf); sprintf(buf,"\\\\.\\pipe\\R2PIPE_IN%x",_getpid()); hPipeInOut = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, PIPE_BUF_SIZE, PIPE_BUF_SIZE, 0, NULL); hproc = myCreateChildProcess (code); if (!hproc) { return false; } bStopThread=FALSE; hThread = CreateThread (NULL, 0,ThreadFunction,lang, 0,0); WaitForSingleObject (hproc, INFINITE ); bStopThread = TRUE; DeleteFile (buf); WaitForSingleObject (hThread, INFINITE); CloseHandle (hPipeInOut); return true; #endif #endif }
// TODO: add support for byte-per-byte opcode search R_API RList *r_core_asm_strsearch(RCore *core, const char *input, ut64 from, ut64 to) { RCoreAsmHit *hit; RAsmOp op; RList *hits; ut64 at, toff = core->offset; ut8 *buf; char *tok, *tokens[1024], *code = NULL, *ptr; int idx, tidx = 0, ret, len; int tokcount, matchcount; if (!*input) return NULL; if (core->blocksize<=OPSZ) { eprintf ("error: block size too small\n"); return NULL; } if (!(buf = (ut8 *)malloc (core->blocksize))) return NULL; if (!(ptr = strdup (input))) { free (buf); return NULL; } if (!(hits = r_core_asm_hit_list_new ())) { free (buf); free (ptr); return NULL; } tokens[0] = NULL; for (tokcount=0; tokcount<(sizeof (tokens) / sizeof (char*)) - 1; tokcount++) { tok = strtok (tokcount? NULL: ptr, ","); if (tok == NULL) break; tokens[tokcount] = r_str_trim_head_tail (tok); } tokens[tokcount] = NULL; r_cons_break (NULL, NULL); for (at = from, matchcount = 0; at < to; at += core->blocksize-OPSZ) { if (r_cons_singleton ()->breaked) break; ret = r_io_read_at (core->io, at, buf, core->blocksize); if (ret != core->blocksize) break; idx = 0, matchcount = 0; while (idx<core->blocksize) { r_asm_set_pc (core->assembler, at+idx); op.buf_asm[0] = 0; op.buf_hex[0] = 0; if (!(len = r_asm_disassemble (core->assembler, &op, buf+idx, core->blocksize-idx))) { idx = (matchcount)? tidx+1: idx+1; matchcount = 0; continue; } if (tokens[matchcount] && strstr (op.buf_asm, tokens[matchcount])) { code = r_str_concatf (code, "%s", op.buf_asm); if (matchcount == tokcount-1) { if (tokcount == 1) tidx = idx; if (!(hit = r_core_asm_hit_new ())) { r_list_purge (hits); free (hits); hits = NULL; goto beach; } hit->addr = at+tidx; hit->len = idx+len-tidx; if (hit->len == -1) { r_core_asm_hit_free (hit); goto beach; } hit->code = strdup (code); r_list_append (hits, hit); R_FREE (code); matchcount = 0; idx = tidx+1; } else if (matchcount == 0) { tidx = idx; matchcount++; idx += len; } else { matchcount++; idx += len; } } else { idx = matchcount? tidx+1: idx+1; R_FREE (code); matchcount = 0; } } } r_asm_set_pc (core->assembler, toff); beach: free (buf); free (ptr); free (code); return hits; }
R_API int r_debug_continue_kill(RDebug *dbg, int sig) { ut64 pc; int retwait, ret = R_FALSE; if (!dbg) return R_FALSE; #if __WINDOWS__ r_cons_break(w32_break_process, dbg); #endif repeat: if (r_debug_is_dead (dbg)) return R_FALSE; if (dbg->h && dbg->h->cont) { r_bp_restore (dbg->bp, R_TRUE); // set sw breakpoints ret = dbg->h->cont (dbg, dbg->pid, dbg->tid, sig); dbg->reason.signum = 0; retwait = r_debug_wait (dbg); #if __WINDOWS__ if (retwait != R_DEBUG_REASON_DEAD) { ret = dbg->tid; } #endif r_bp_restore (dbg->bp, R_FALSE); // unset sw breakpoints //r_debug_recoil (dbg); if (r_debug_recoil (dbg) || (dbg->reason.type == R_DEBUG_REASON_BREAKPOINT)) { /* check if cur bp demands tracing or not */ pc = r_debug_reg_get (dbg, dbg->reg->name[R_REG_NAME_PC]); RBreakpointItem *b = r_bp_get_at (dbg->bp, pc); if (b) { /* check if cur bp demands tracing or not */ if (b->trace) { eprintf("hit tracepoit at: %"PFMT64x"\n",pc); } else { eprintf("hit breakpoint at: %"PFMT64x"\n",pc); } if (dbg->trace->enabled) r_debug_trace_pc (dbg); // TODO: delegate this to RCore.bphit(RCore, RBreakopintItem) if (dbg->corebind.core && dbg->corebind.bphit) { dbg->corebind.bphit (dbg->corebind.core, b); } if (b->trace) { r_debug_step (dbg, 1); goto repeat; } } } #if 0 #if __UNIX__ /* XXX Uh? */ if (dbg->stop_all_threads && dbg->pid>0) r_sandbox_kill (dbg->pid, SIGSTOP); #endif #endif r_debug_select (dbg, dbg->pid, ret); sig = 0; // clear continuation after signal if needed if (retwait == R_DEBUG_REASON_SIGNAL && dbg->reason.signum != -1) { int what = r_debug_signal_what (dbg, dbg->reason.signum); if (what & R_DBG_SIGNAL_CONT) { sig = dbg->reason.signum; eprintf ("Continue into the signal %d handler\n", sig); goto repeat; } else if (what & R_DBG_SIGNAL_SKIP) { // skip signal. requires skipping one instruction ut8 buf[64]; RAnalOp op = {0}; ut64 pc = r_debug_reg_get (dbg, "pc"); dbg->iob.read_at (dbg->iob.io, pc, buf, sizeof (buf)); r_anal_op (dbg->anal, &op, pc, buf, sizeof (buf)); if (op.size>0) { const char *signame = r_debug_signal_resolve_i (dbg, dbg->reason.signum); r_debug_reg_set (dbg, "pc", pc+op.size); eprintf ("Skip signal %d handler %s\n", dbg->reason.signum, signame); goto repeat; } else { ut64 pc = r_debug_reg_get (dbg, "pc"); eprintf ("Stalled with an exception at 0x%08"PFMT64x"\n", pc); } } } } return ret; }
static int lang_pipe_run(RLang *lang, const char *code, int len) { #if __UNIX__ int safe_in = dup (0); int child, ret; int input[2]; int output[2]; pipe (input); pipe (output); env ("R2PIPE_IN", input[0]); env ("R2PIPE_OUT", output[1]); child = r_sys_fork (); if (child == -1) { /* error */ } else if (child == 0) { /* children */ #if 1 r_sandbox_system (code, 1); #else /* DEMO */ char buf[1024]; /* kid stuff here */ while (1) { write (output[1], "pd 3\n", 6); res = read (input[0], buf, sizeof (buf)-1); if (res <1) break; printf ("---> ((%s))\n", buf); sleep (1); } #endif write (input[1], "", 1); close (input[0]); close (input[1]); close (output[0]); close (output[1]); exit (0); return R_FALSE; } else { /* parent */ char *res, buf[1024]; /* Close pipe ends not required in the parent */ close(output[1]); close(input[0]); r_cons_break (NULL, NULL); for (;;) { if (r_cons_singleton ()->breaked) { break; } memset (buf, 0, sizeof (buf)); ret = read (output[0], buf, sizeof (buf)-1); if (ret <1 || !buf[0]) { break; } buf[sizeof (buf)-1] = 0; res = lang->cmd_str ((RCore*)lang->user, buf); //eprintf ("%d %s\n", ret, buf); if (res) { write (input[1], res, strlen (res)+1); free (res); } else { eprintf ("r_lang_pipe: NULL reply for (%s)\n", buf); write (input[1], "", 1); // NULL byte } } /* workaround to avoid stdin closed */ if (safe_in != -1) close (safe_in); safe_in = open (ttyname(0), O_RDONLY); if (safe_in != -1) { dup2 (safe_in, 0); } else eprintf ("Cannot open ttyname(0) %s\n", ttyname(0)); r_cons_break_end (); } close (input[0]); close (input[1]); close (output[0]); close (output[1]); if (safe_in != -1) close (safe_in); waitpid (child, NULL, 0); return R_TRUE; #else #if __WINDOWS__ HANDLE hPipeInOut = NULL; HANDLE hproc=NULL; DWORD dwRead, dwWritten; CHAR buf[1024]; BOOL bSuccess = FALSE; int res=0; sprintf(buf,"R2PIPE_IN%x",_getpid()); SetEnvironmentVariable("R2PIPE_PATH",buf); sprintf(buf,"\\\\.\\pipe\\R2PIPE_IN%x",_getpid()); hPipeInOut = CreateNamedPipe(buf, PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE | \ PIPE_READMODE_MESSAGE | \ PIPE_NOWAIT,PIPE_UNLIMITED_INSTANCES, sizeof (buf), sizeof (buf), 0, NULL); hproc=myCreateChildProcess (code); if (hproc==NULL) { //eprintf("Error spawning process: %s\n",code); return R_TRUE; } r_cons_break (NULL, NULL); for (;;) { res = ConnectNamedPipe(hPipeInOut, NULL); if (GetLastError()==ERROR_PIPE_CONNECTED) { //eprintf("new client\n"); break; } if (r_cons_singleton ()->breaked) { TerminateProcess(hproc,0); break; } } for (;;) { if (r_cons_singleton ()->breaked) { TerminateProcess(hproc,0); break; } memset (buf, 0, sizeof (buf)); bSuccess = ReadFile( hPipeInOut, buf, sizeof (buf), &dwRead, NULL); if (dwRead!=0) { buf[sizeof(buf)-1] = 0; res = lang->cmd_str ((RCore*)lang->user, buf); if (res) { WriteFile(hPipeInOut, res, strlen (res)+1, &dwWritten, NULL); free (res); } else { WriteFile(hPipeInOut, "", 1, &dwWritten, NULL); } } } CloseHandle(hPipeInOut); r_cons_break_end (); return R_TRUE; #endif #endif }
static int bin_strings(RCore *r, int mode, int va) { char *q, str[R_FLAG_NAME_SIZE]; RBinSection *section; int hasstr, minstr, maxstr, rawstr; RBinString *string; RListIter *iter; RList *list; RBin *bin = r->bin; RBinFile * binfile = r_core_bin_cur (r); RBinPlugin *plugin = r_bin_file_cur_plugin (binfile); if (!binfile) return false; minstr = r_config_get_i (r->config, "bin.minstr"); maxstr = r_config_get_i (r->config, "bin.maxstr"); rawstr = r_config_get_i (r->config, "bin.rawstr"); binfile->rawstr = rawstr; if (!(hasstr = r_config_get_i (r->config, "bin.strings"))) { return 0; } if (!plugin) return 0; if (plugin->info && plugin->name) { if (strcmp (plugin->name, "any") == 0 && !rawstr) { return false; } } bin->minstrlen = minstr; minstr = bin->minstrlen; if ((list = r_bin_get_strings (bin)) == NULL) return false; if (IS_MODE_JSON (mode)) r_cons_printf ("["); if (IS_MODE_RAD (mode)) r_cons_printf ("fs strings"); if (IS_MODE_SET (mode) && r_config_get_i (r->config, "bin.strings")) { r_flag_space_set (r->flags, "strings"); r_cons_break (NULL, NULL); } r_list_foreach (list, iter, string) { const char *section_name, *type_string; ut64 paddr = string->paddr; ut64 vaddr = r_bin_get_vaddr (bin, paddr, string->vaddr); ut64 addr = va ? vaddr : paddr; if (string->length < minstr) continue; if (maxstr && string->length > maxstr) continue; section = r_bin_get_section_at (r_bin_cur_object (bin), paddr, 0); section_name = section ? section->name : "unknown"; type_string = string->type == 'w' ? "wide" : "ascii"; if (IS_MODE_SET (mode)) { char *f_name; if (r_cons_singleton()->breaked) break; r_meta_add (r->anal, R_META_TYPE_STRING, addr, addr + string->size, string->string); f_name = strdup (string->string); r_name_filter (f_name, R_FLAG_NAME_SIZE); snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name); r_flag_set (r->flags, str, addr, string->size, 0); free (f_name); } else if (IS_MODE_SIMPLE (mode)) { r_cons_printf ("0x%"PFMT64x" %d %d %s\n", addr, string->size, string->length, string->string); } else if (IS_MODE_JSON (mode)) { q = r_base64_encode_dyn (string->string, -1); r_cons_printf ("%s{\"vaddr\":%"PFMT64d ",\"paddr\":%"PFMT64d",\"ordinal\":%d" ",\"size\":%d,\"length\":%d,\"section\":\"%s\"," "\"type\":\"%s\",\"string\":\"%s\"}", iter->p ? ",": "", vaddr, paddr, string->ordinal, string->size, string->length, section_name, type_string, q); free (q); } else if (IS_MODE_RAD (mode)) { char *f_name; f_name = strdup (string->string); r_name_filter (f_name, R_FLAG_NAME_SIZE); snprintf (str, R_FLAG_NAME_SIZE, "str.%s", f_name); r_cons_printf ("f str.%s %"PFMT64d" @ 0x%08"PFMT64x"\n" "Cs %"PFMT64d" @ 0x%08"PFMT64x"\n", f_name, string->size, addr, string->size, addr); free (f_name); } else { r_cons_printf ("vaddr=0x%08"PFMT64x" paddr=0x%08" PFMT64x" ordinal=%03u sz=%u len=%u " "section=%s type=%s string=%s\n", vaddr, paddr, string->ordinal, string->size, string->length, section_name, type_string, string->string); } } if (IS_MODE_JSON (mode)) r_cons_printf ("]"); if (IS_MODE_SET (mode)) r_cons_break_end (); return true; }
- follow symlinks #endif R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { RSocketHTTPRequest *rs; int oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); while (!r_cons_singleton ()->breaked) { r_cons_break (http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (200); continue; } if (!rs->method || !rs->path) { r_socket_http_close (rs); continue; } if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = strdup ("<html><body>\n"); const char *file; RListIter *iter; // list files RList *files = r_sys_dir (uproot); eprintf ("Listing directory %s\n", uproot); r_list_foreach (files, iter, file) { if (file[0] == '.') continue; ptr = r_str_concatf (ptr, "<a href=\"/up/%s\">%s</a><br />\n", file, file); } r_list_free (files); ptr = r_str_concat (ptr, "<html><body>\n"); r_socket_http_response (rs, 200, ptr, 0, NULL); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) {
R_API int r_core_rtr_http(RCore *core, int launch, const char *path) { char buf[32]; RSocketHTTPRequest *rs; int iport, oldsandbox = -1; int timeout = r_config_get_i (core->config, "http.timeout"); int x = r_config_get_i (core->config, "scr.html"); int y = r_config_get_i (core->config, "scr.color"); int z = r_config_get_i (core->config, "asm.bytes"); int u = r_config_get_i (core->config, "scr.interactive"); int v = r_config_get_i (core->config, "asm.cmtright"); const char *port = r_config_get (core->config, "http.port"); char *allow = (char *)r_config_get (core->config, "http.allow"); if (core->http_up) { eprintf ("http server is already running\n"); return 1; } if (r_sandbox_enable (0)) { eprintf ("sandbox: connect disabled\n"); return 1; } if (path && atoi (path)) { port = path; path = NULL; } if (!strcmp (port, "0")) { r_num_irand (); iport = 1024+r_num_rand (45256); snprintf (buf, sizeof (buf), "%d", iport); port = buf; } s = r_socket_new (R_FALSE); s->local = !r_config_get_i (core->config, "http.public"); if (!r_socket_listen (s, port, NULL)) { eprintf ("Cannot listen on http.port\n"); return 1; } if (launch) { char cmd[128]; const char *browser = r_config_get (core->config, "http.browser"); snprintf (cmd, sizeof (cmd)-1, "%s http://localhost:%d/%s &", browser, atoi (port), path?path:""); r_sys_cmd (cmd); } r_config_set (core->config, "asm.cmtright", "false"); r_config_set (core->config, "scr.html", "true"); r_config_set (core->config, "scr.color", "false"); r_config_set (core->config, "asm.bytes", "false"); r_config_set (core->config, "scr.interactive", "false"); if (r_config_get_i (core->config, "http.sandbox")) { oldsandbox = r_config_get_i (core->config, "cfg.sandbox"); r_config_set (core->config, "cfg.sandbox", "true"); } eprintf ("Starting http server...\n"); eprintf ("http://localhost:%d/\n", atoi (port)); core->http_up = R_TRUE; while (!r_cons_singleton ()->breaked) { r_cons_break ((RConsBreak)http_break, core); rs = r_socket_http_accept (s, timeout); if (!rs) { if (!s) break; r_sys_usleep (100); continue; } if (allow && *allow) { int accepted = R_FALSE; const char *host; char *p, *peer = r_socket_to_string (rs->s); char *allows = strdup (allow); //eprintf ("Firewall (%s)\n", allows); int i, count = r_str_split (allows, ','); p = strchr (peer, ':'); if (p) *p = 0; for (i=0; i<count; i++) { host = r_str_word_get0 (allows, i); //eprintf ("--- (%s) (%s)\n", host, peer); if (!strcmp (host, peer)) { accepted = R_TRUE; break; } } free (peer); free (allows); if (!accepted) { r_socket_http_close (rs); continue; } } if (!rs->method || !rs->path) { eprintf ("Invalid http headers received from client\n"); r_socket_http_close (rs); continue; } char *dir = NULL; if (r_config_get_i (core->config, "http.dirlist")) if (r_file_is_directory (rs->path)) dir = strdup (rs->path); if (!strcmp (rs->method, "GET")) { if (!memcmp (rs->path, "/up", 3)) { if (r_config_get_i (core->config, "http.upget")) { const char *uproot = r_config_get (core->config, "http.uproot"); if (!rs->path[3] || (rs->path[3]=='/'&&!rs->path[4])) { char *ptr = rtr_dir_files (uproot); r_socket_http_response (rs, 200, ptr, 0, NULL); free (ptr); } else { char *path = r_file_root (uproot, rs->path + 4); if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { r_socket_http_response (rs, 200, f, sz, NULL); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else { r_socket_http_response (rs, 403, "Permission denied\n", 0, NULL); } } else if (!memcmp (rs->path, "/cmd/", 5)) { char *cmd = rs->path +5; char foo[32]; const char *httpcmd = r_config_get (core->config, "http.uri"); while (*cmd=='/') cmd++; if (httpcmd && *httpcmd) { int len; char *res; // do remote http query and proxy response snprintf (foo, sizeof (foo), "%s/%s", httpcmd, cmd); res = r_socket_http_get (foo, NULL, &len); if (res) { res[len]=0; r_cons_printf ("%s\n", res); } } else { char *out, *cmd = rs->path+5; r_str_uri_decode (cmd); // eprintf ("CMD (%s)\n", cmd); out = r_core_cmd_str_pipe (core, cmd); // eprintf ("\nOUT LEN = %d\n", strlen (out)); if (out) { char *res = r_str_uri_encode (out); r_socket_http_response (rs, 200, out, 0, "Content-Type: text/plain\n"); free (out); free (res); } else r_socket_http_response (rs, 200, "", 0, NULL); } } else { const char *root = r_config_get (core->config, "http.root"); char *path = r_file_root (root, rs->path); // FD IS OK HERE if (rs->path [strlen (rs->path)-1] == '/') { path = r_str_concat (path, "index.html"); //rs->path = r_str_concat (rs->path, "index.html"); } else { //snprintf (path, sizeof (path), "%s/%s", root, rs->path); if (r_file_is_directory (path)) { char res[128]; snprintf (res, sizeof (res), "Location: %s/\n", rs->path); r_socket_http_response (rs, 302, NULL, 0, res); r_socket_http_close (rs); free (path); free (dir); dir = NULL; continue; } } if (r_file_exists (path)) { int sz = 0; char *f = r_file_slurp (path, &sz); if (f) { const char *contenttype = NULL; if (strstr (path, ".js")) contenttype = "Content-Type: application/javascript\n"; if (strstr (path, ".css")) contenttype = "Content-Type: text/css\n"; if (strstr (path, ".html")) contenttype = "Content-Type: text/html\n"; r_socket_http_response (rs, 200, f, sz, contenttype); free (f); } else { r_socket_http_response (rs, 403, "Permission denied", 0, NULL); eprintf ("http: Cannot open '%s'\n", path); } } else { if (dir) { char *resp = rtr_dir_files (dir); eprintf ("Dirlisting %s\n", dir); r_socket_http_response (rs, 404, resp, 0, NULL); free (resp); } else { eprintf ("File '%s' not found\n", path); r_socket_http_response (rs, 404, "File not found\n", 0, NULL); } } free (path); } } else if (!strcmp (rs->method, "POST")) { ut8 *ret; int retlen; char buf[128]; if (r_config_get_i (core->config, "http.upload")) { ret = r_socket_http_handle_upload ( rs->data, rs->data_length, &retlen); if (ret) { ut64 size = r_config_get_i (core->config, "http.maxsize"); if (size && retlen > size) { r_socket_http_response (rs, 403, "403 File too big\n", 0, NULL); } else { char *filename = r_file_root ( r_config_get (core->config, "http.uproot"), rs->path + 4); eprintf ("UPLOADED '%s'\n", filename); r_file_dump (filename, ret, retlen); free (filename); snprintf (buf, sizeof (buf), "<html><body><h2>uploaded %d bytes. Thanks</h2>\n", retlen); r_socket_http_response (rs, 200, buf, 0, NULL); } free (ret); } } else { r_socket_http_response (rs, 403, "403 Forbidden\n", 0, NULL); } } else { r_socket_http_response (rs, 404, "Invalid protocol", 0, NULL); } r_socket_http_close (rs); free (dir); } core->http_up = R_FALSE; r_socket_free (s); r_cons_break_end (); r_config_set_i (core->config, "scr.html", x); r_config_set_i (core->config, "scr.color", y); r_config_set_i (core->config, "asm.bytes", z); r_config_set_i (core->config, "scr.interactive", u); r_config_set_i (core->config, "asm.cmtright", v); if (oldsandbox != -1) r_config_set_i (core->config, "cfg.sandbox", oldsandbox); return 0; }