Rizin
unix-like reverse engineering framework and cli tools
rtr.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2009-2020 nibble <nibble.ds@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include "rz_core.h"
6 #include "rz_socket.h"
7 #include <libgdbr.h>
8 #include <gdbserver/core.h>
9 
10 #if HAVE_LIBUV
11 #include <uv.h>
12 #endif
13 
14 #if 0
15 SECURITY IMPLICATIONS
16 =====================
17 - no ssl
18 - no auth
19 - commands can be executed by anyone
20 - default is to listen on localhost
21 - can access full filesystem
22 - follow symlinks
23 #endif
24 
25 #define rtr_n core->rtr_n
26 #define rtr_host core->rtr_host
27 
28 static RzSocket *s = NULL;
30 static const char *listenport = NULL;
31 
33  int proto;
34  char host[512];
35  int port;
36  char file[1024];
38 };
39 
40 typedef struct {
41  const char *host;
42  const char *port;
43  const char *file;
44 } TextLog;
45 
46 typedef struct {
48  char *input;
50 } RapThread;
51 
52 RZ_API void rz_core_wait(RzCore *core) {
54  if (rapthread) {
56  rz_atomic_bool_set(rt->loop, false);
58  }
59 }
60 
61 static void http_logf(RzCore *core, const char *fmt, ...) {
62  bool http_log_enabled = rz_config_get_i(core->config, "http.log");
63  va_list ap;
64  va_start(ap, fmt);
65  if (http_log_enabled) {
66  const char *http_log_file = rz_config_get(core->config, "http.logfile");
67  if (http_log_file && *http_log_file) {
68  char *msg = calloc(4096, 1);
69  if (msg) {
70  vsnprintf(msg, 4095, fmt, ap);
71  rz_file_dump(http_log_file, (const ut8 *)msg, -1, true);
72  free(msg);
73  }
74  } else {
75  vfprintf(stderr, fmt, ap);
76  }
77  }
78  va_end(ap);
79 }
80 
81 static char *rtrcmd(TextLog T, const char *str) {
82  char *res, *ptr2;
83  char *ptr = rz_str_uri_encode(str);
84  char *uri = rz_str_newf("http://%s:%s/%s%s", T.host, T.port, T.file, ptr ? ptr : str);
85  int len;
86  free(ptr);
87  ptr2 = rz_socket_http_get(uri, NULL, &len);
88  free(uri);
89  if (ptr2) {
90  ptr2[len] = 0;
91  res = strstr(ptr2, "\n\n");
92  if (res) {
93  res = strstr(res + 1, "\n\n");
94  }
95  return res ? res + 2 : ptr2;
96  }
97  return NULL;
98 }
99 
100 static void showcursor(RzCore *core, int x) {
101  if (core && core->vmode) {
103  rz_cons_enable_mouse(x ? rz_config_get_i(core->config, "scr.wheel") : false);
104  } else {
105  rz_cons_enable_mouse(false);
106  }
107  rz_cons_flush();
108 }
109 
111  RzCore *core = (RzCore *)u;
112  const int timeout = 1; // 1 second
113  const char *port;
114  RzSocket *sock;
115 
116 #if __WINDOWS__
118 #endif
119  if (((size_t)u) > 0xff) {
120  port = listenport ? listenport : rz_config_get(core->config, "http.port");
121  sock = rz_socket_new(0);
122  (void)rz_socket_connect(sock, "localhost",
124  rz_socket_free(sock);
125  }
126  rz_socket_free(s);
127  s = NULL;
128  return 0;
129 }
130 
131 static char *rtr_dir_files(const char *path) {
132  char *ptr = strdup("<html><body>\n");
133  const char *file;
134  RzListIter *iter;
135  // list files
137  eprintf("Listing directory %s\n", path);
138  rz_list_foreach (files, iter, file) {
139  if (file[0] == '.') {
140  continue;
141  }
142  ptr = rz_str_appendf(ptr, "<a href=\"%s%s\">%s</a><br />\n",
143  path, file, file);
144  }
146  return rz_str_append(ptr, "</body></html>\n");
147 }
148 
149 #if __UNIX__
150 static void dietime(int sig) {
151  eprintf("It's Die Time!\n");
152  exit(0);
153 }
154 #endif
155 
156 static void activateDieTime(RzCore *core) {
157  int dt = rz_config_get_i(core->config, "http.dietime");
158  if (dt > 0) {
159 #if __UNIX__
160  rz_sys_signal(SIGALRM, dietime);
161  alarm(dt);
162 #else
163  eprintf("http.dietime only works on *nix systems\n");
164 #endif
165  }
166 }
167 
168 #include "rtr_http.c"
169 #include "rtr_shell.c"
170 
171 static int write_reg_val(char *buf, ut64 sz, ut64 reg, int regsize, bool bigendian) {
172  if (!bigendian) {
173  switch (regsize) {
174  case 2:
175  reg = rz_swap_ut16(reg);
176  break;
177  case 4:
178  reg = rz_swap_ut32(reg);
179  break;
180  case 8:
181  reg = rz_swap_ut64(reg);
182  break;
183  default:
184  eprintf("%s: Unsupported reg size: %d\n",
185  __func__, regsize);
186  return -1;
187  }
188  }
189  return snprintf(buf, sz, regsize == 2 ? "%04" PFMT64x : regsize == 4 ? "%08" PFMT64x
190  : "%016" PFMT64x,
191  reg);
192 }
193 
194 static int write_big_reg(char *buf, ut64 sz, const utX *val, int regsize, bool bigendian) {
195  switch (regsize) {
196  case 10:
197  if (bigendian) {
198  return snprintf(buf, sz,
199  "%04x%016" PFMT64x, val->v80.High,
200  val->v80.Low);
201  }
202  return snprintf(buf, sz,
203  "%016" PFMT64x "%04x", rz_swap_ut64(val->v80.Low),
204  rz_swap_ut16(val->v80.High));
205  case 12:
206  if (bigendian) {
207  return snprintf(buf, sz,
208  "%08" PFMT32x "%016" PFMT64x, val->v96.High,
209  val->v96.Low);
210  }
211  return snprintf(buf, sz,
212  "%016" PFMT64x "%08" PFMT32x, rz_swap_ut64(val->v96.Low),
213  rz_swap_ut32(val->v96.High));
214  case 16:
215  if (bigendian) {
216  return snprintf(buf, sz,
217  "%016" PFMT64x "%016" PFMT64x, val->v128.High,
218  val->v128.Low);
219  }
220  return snprintf(buf, sz,
221  "%016" PFMT64x "%016" PFMT64x,
222  rz_swap_ut64(val->v128.Low),
223  rz_swap_ut64(val->v128.High));
224  default:
225  eprintf("%s: big registers (%d byte(s)) not yet supported\n",
226  __func__, regsize);
227  return -1;
228  }
229 }
230 
231 static int swap_big_regs(char *dest, ut64 sz, const char *src, int regsz) {
232  utX val;
233  char sdup[128] = { 0 };
234  if (!src || !src[0] || !src[1]) {
235  return -1;
236  }
237  strncpy(sdup, src + 2, sizeof(sdup) - 1);
238  int len = strlen(sdup);
239  memset(&val, 0, sizeof(val));
240  switch (regsz) {
241  case 10:
242  if (len <= 4) {
243  val.v80.High = (ut16)strtoul(sdup, NULL, 16);
244  } else {
245  val.v80.High = (ut16)strtoul(sdup + (len - 4), NULL, 16);
246  sdup[len - 4] = '\0';
247  val.v80.Low = (ut64)strtoull(sdup, NULL, 16);
248  }
249  return snprintf(dest, sz, "0x%04x%016" PFMT64x,
250  val.v80.High, val.v80.Low);
251  case 12:
252  if (len <= 8) {
253  val.v96.High = (ut32)strtoul(sdup, NULL, 16);
254  } else {
255  val.v96.High = (ut32)strtoul(sdup + (len - 8), NULL, 16);
256  sdup[len - 8] = '\0';
257  val.v96.Low = (ut64)strtoull(sdup, NULL, 16);
258  }
259  return snprintf(dest, sz, "0x%08x%016" PFMT64x,
260  val.v96.High, val.v96.Low);
261  case 16:
262  if (len <= 16) {
263  val.v128.High = (ut64)strtoul(sdup, NULL, 16);
264  } else {
265  val.v128.High = (ut64)strtoul(sdup + (len - 16), NULL, 16);
266  sdup[len - 16] = '\0';
267  val.v128.Low = (ut64)strtoull(sdup, NULL, 16);
268  }
269  return snprintf(dest, sz, "0x%016" PFMT64x "%016" PFMT64x,
270  val.v128.High, val.v128.Low);
271  default:
272  eprintf("%s: big registers (%d byte(s)) not yet supported\n",
273  __func__, regsz);
274  return -1;
275  }
276 }
277 
278 static int rz_core_rtr_gdb_cb(libgdbr_t *g, void *core_ptr, const char *cmd,
279  char *out_buf, size_t max_len) {
280  int ret;
281  RzList *list;
282  RzListIter *iter;
284  RzRegItem *r;
285  utX val_big;
286  ut64 m_off, reg_val;
287  bool be;
288  RzDebugPid *dbgpid;
289  if (!core_ptr || !cmd) {
290  return -1;
291  }
292  RzCore *core = (RzCore *)core_ptr;
293  switch (cmd[0]) {
294  case '?': // Stop reason
295  if (!out_buf) {
296  return -1;
297  }
298  // dbg->reason.signum and dbg->reason.tid are not correct for native
299  // debugger. This is a hack
300  switch (core->dbg->reason.type) {
304  default: // remove when possible
305  return snprintf(out_buf, max_len - 1, "T05thread:%x;",
306  core->dbg->tid);
307  }
308  // Fallback for when it's fixed
309  /*
310  return snprintf (out_buf, max_len - 1, "T%02xthread:%x;",
311  core->dbg->reason.type, core->dbg->reason.tid);
312  */
313  case 'd':
314  switch (cmd[1]) {
315  case 'm': // dm
316  if (snprintf(out_buf, max_len - 1, "%" PFMT64x, rz_debug_get_baddr(core->dbg, NULL)) < 0) {
317  return -1;
318  }
319  return 0;
320  case 'p': // dp
321  switch (cmd[2]) {
322  case '\0': // dp
323  // TODO support multiprocess
324  snprintf(out_buf, max_len - 1, "QC%x", core->dbg->tid);
325  return 0;
326  case 't':
327  switch (cmd[3]) {
328  case '\0': // dpt
329  if (!core->dbg->cur->threads) {
330  return -1;
331  }
332  if (!(list = core->dbg->cur->threads(core->dbg, core->dbg->pid))) {
333  return -1;
334  }
335  memset(out_buf, 0, max_len);
336  out_buf[0] = 'm';
337  ret = 1;
338  rz_list_foreach (list, iter, dbgpid) {
339  // Max length of a hex pid = 8?
340  if (ret >= max_len - 9) {
341  break;
342  }
343  snprintf(out_buf + ret, max_len - ret - 1, "%x,", dbgpid->pid);
344  ret = strlen(out_buf);
345  }
346  if (ret > 1) {
347  ret--;
348  out_buf[ret] = '\0';
349  }
350  return 0;
351  case 'r': // dptr -> return current tid as int
352  return core->dbg->tid;
353  default:
354  return rz_core_cmd(core, cmd, 0);
355  }
356  }
357  break;
358  case 'r': // dr
359  rz_debug_reg_sync(core->dbg, RZ_REG_TYPE_ANY, false);
360  be = rz_config_get_i(core->config, "cfg.bigendian");
361  if (isspace((ut8)cmd[2])) { // dr reg
362  const char *name, *val_ptr;
363  char new_cmd[128] = { 0 };
364  int off = 0;
365  name = cmd + 3;
366  // Temporarily using new_cmd to store reg name
367  if ((val_ptr = strchr(name, '='))) {
368  strncpy(new_cmd, name, RZ_MIN(val_ptr - name, sizeof(new_cmd) - 1));
369  } else {
370  strncpy(new_cmd, name, sizeof(new_cmd) - 1);
371  }
372  if (!(r = rz_reg_get(core->dbg->reg, new_cmd, -1))) {
373  return -1;
374  }
375  if (val_ptr) { // dr reg=val
376  val_ptr++;
377  off = val_ptr - cmd;
378  if (be) {
379  // We don't need to swap
380  rz_core_cmd(core, cmd, 0);
381  }
382  // Previous contents are overwritten, since len(name) < off
383  strncpy(new_cmd, cmd, off);
384  if (r->size <= 64) {
385  reg_val = strtoll(val_ptr, NULL, 16);
386  if (write_reg_val(new_cmd + off, sizeof(new_cmd) - off - 1,
387  reg_val, r->size / 8, be) < 0) {
388  return -1;
389  }
390  return rz_core_cmd(core, new_cmd, 0);
391  }
392  // Big registers
393  if (swap_big_regs(new_cmd + off, sizeof(new_cmd) - off - 1,
394  val_ptr, r->size / 8) < 0) {
395  return -1;
396  }
397  return rz_core_cmd(core, new_cmd, 0);
398  }
399  if (r->size <= 64) {
400  reg_val = rz_reg_get_value(core->dbg->reg, r);
401  return write_reg_val(out_buf, max_len - 1,
402  reg_val, r->size / 8, be);
403  }
405  r, &val_big);
406  return write_big_reg(out_buf, max_len - 1,
407  &val_big, r->size / 8, be);
408  }
409  // dr - Print all registers
410  ret = 0;
411  if (!(gdb_reg = g->registers)) {
412  return -1;
413  }
414  while (*gdb_reg->name) {
415  if (ret + gdb_reg->size * 2 >= max_len - 1) {
416  return -1;
417  }
418  if (gdb_reg->size <= 8) {
419  reg_val = rz_reg_getv(core->dbg->reg, gdb_reg->name);
420  if (write_reg_val(out_buf + ret,
421  gdb_reg->size * 2 + 1,
422  reg_val, gdb_reg->size, be) < 0) {
423  return -1;
424  }
425  } else {
427  rz_reg_get(core->dbg->reg, gdb_reg->name, -1),
428  &val_big);
429  if (write_big_reg(out_buf + ret, gdb_reg->size * 2 + 1,
430  &val_big, gdb_reg->size, be) < 0) {
431  return -1;
432  }
433  }
434  ret += gdb_reg->size * 2;
435  gdb_reg++;
436  }
437  out_buf[ret] = '\0';
438  return ret;
439  default:
440  return rz_core_cmd(core, cmd, 0);
441  }
442  break;
443  case 'i':
444  switch (cmd[1]) {
445  case 'f': {
446  ut64 off, len, sz, namelen;
447  RzIODesc *desc = core && core->file ? rz_io_desc_get(core->io, core->file->fd) : NULL;
448  if (sscanf(cmd + 2, "%" PFMT64x ",%" PFMT64x, &off, &len) != 2) {
449  strcpy(out_buf, "E00");
450  return 0;
451  }
452  namelen = desc ? strlen(desc->name) : 0;
453  if (off >= namelen) {
454  out_buf[0] = 'l';
455  return 0;
456  }
457  sz = RZ_MIN(max_len, len + 2);
458  len = snprintf(out_buf, sz, "l%s", desc ? (desc->name + off) : "");
459  if (len >= sz) {
460  // There's more left
461  out_buf[0] = 'm';
462  }
463  return 0;
464  }
465  }
466  break;
467  case 'm':
468  sscanf(cmd + 1, "%" PFMT64x ",%x", &m_off, &ret);
469  if (rz_io_read_at(core->io, m_off, (ut8 *)out_buf, ret)) {
470  return ret;
471  }
472  return -1;
473  default:
474  return rz_core_cmd(core, cmd, 0);
475  }
476  return -1;
477 }
478 
479 // path = "<port> <file_name>"
480 static int rz_core_rtr_gdb_run(RzCore *core, int launch, const char *path) {
481  RzSocket *sock;
482  int p, ret;
483  bool debug_msg = false;
484  char port[10];
485  char *file = NULL, *args = NULL;
486  libgdbr_t *g;
487 
488  if (!core || !path) {
489  return -1;
490  }
491  if (*path == '!') {
492  debug_msg = true;
493  path++;
494  }
495  if (!(path = rz_str_trim_head_ro(path)) || !*path) {
496  eprintf("gdbserver: Port not specified\n");
497  return -1;
498  }
499  if (!(p = atoi(path)) || p < 0 || p > 65535) {
500  eprintf("gdbserver: Invalid port: %s\n", port);
501  return -1;
502  }
503  snprintf(port, sizeof(port) - 1, "%d", p);
504  if (!(file = strchr(path, ' '))) {
505  eprintf("gdbserver: File not specified\n");
506  return -1;
507  }
508  if (!(file = (char *)rz_str_trim_head_ro(file)) || !*file) {
509  eprintf("gdbserver: File not specified\n");
510  return -1;
511  }
512  args = strchr(file, ' ');
513  if (args) {
514  *args++ = '\0';
515  if (!(args = (char *)rz_str_trim_head_ro(args))) {
516  args = "";
517  }
518  } else {
519  args = "";
520  }
521 
522  if (!rz_core_file_open(core, file, RZ_PERM_R, 0)) {
523  eprintf("Cannot open file (%s)\n", file);
524  return -1;
525  }
526  ut64 baddr = rz_config_get_i(core->config, "bin.baddr");
527  rz_core_bin_load(core, NULL, baddr);
529 
530  if (!(sock = rz_socket_new(false))) {
531  eprintf("gdbserver: Could not open socket for listening\n");
532  return -1;
533  }
534  if (!rz_socket_listen(sock, port, NULL)) {
535  rz_socket_free(sock);
536  eprintf("gdbserver: Cannot listen on port: %s\n", port);
537  return -1;
538  }
539  if (!(g = RZ_NEW0(libgdbr_t))) {
540  rz_socket_free(sock);
541  eprintf("gdbserver: Cannot alloc libgdbr instance\n");
542  return -1;
543  }
544  gdbr_init(g, true);
545  g->server_debug = debug_msg;
546  int arch = rz_sys_arch_id(rz_config_get(core->config, "asm.arch"));
547  int bits = rz_config_get_i(core->config, "asm.bits");
549  core->gdbserver_up = 1;
550  eprintf("gdbserver started on port: %s, file: %s\n", port, file);
551 
552  for (;;) {
553  if (!(g->sock = rz_socket_accept(sock))) {
554  break;
555  }
556  g->connected = 1;
557  ret = gdbr_server_serve(g, rz_core_rtr_gdb_cb, (void *)core);
558  rz_socket_close(g->sock);
559  g->connected = 0;
560  if (ret < 0) {
561  break;
562  }
563  }
564  core->gdbserver_up = 0;
565  gdbr_cleanup(g);
566  free(g);
567  rz_socket_free(sock);
568  return 0;
569 }
570 
571 RZ_API int rz_core_rtr_gdb(RzCore *core, int launch, const char *path) {
572  int ret;
573  // TODO: do stuff with launch
574  if (core->gdbserver_up) {
575  eprintf("gdbserver is already running\n");
576  return -1;
577  }
578  ret = rz_core_rtr_gdb_run(core, launch, path);
579  return ret;
580 }
581 
582 RZ_API void rz_core_rtr_pushout(RzCore *core, const char *input) {
583  int fd = atoi(input);
584  const char *cmd = NULL;
585  char *str = NULL;
586  if (fd) {
587  for (rtr_n = 0; rtr_host[rtr_n].fd && rtr_n < RTR_MAX_HOSTS - 1; rtr_n++) {
588  if (rtr_host[rtr_n].fd->fd != fd) {
589  continue;
590  }
591  }
592  if (!(cmd = strchr(input, ' '))) {
593  eprintf("Error\n");
594  return;
595  }
596  } else {
597  cmd = input;
598  }
599 
600  if (!rtr_host[rtr_n].fd || !rtr_host[rtr_n].fd->fd) {
601  eprintf("Error: Unknown host\n");
602  return;
603  }
604 
605  if (!(str = rz_core_cmd_str(core, cmd))) {
606  eprintf("Error: rizin_cmd_str returned NULL\n");
607  return;
608  }
609 
610  switch (rtr_host[rtr_n].proto) {
611  case RTR_PROTOCOL_RAP:
612  eprintf("Error: Cannot use '=<' to a rap connection.\n");
613  break;
614  case RTR_PROTOCOL_UNIX:
615  rz_socket_write(rtr_host[rtr_n].fd, str, strlen(str));
616  break;
617  case RTR_PROTOCOL_HTTP:
618  eprintf("TODO\n");
619  break;
620  case RTR_PROTOCOL_TCP:
621  case RTR_PROTOCOL_UDP:
622  rz_socket_write(rtr_host[rtr_n].fd, str, strlen(str));
623  break;
624  default:
625  eprintf("Unknown protocol\n");
626  break;
627  }
628  free(str);
629 }
630 
632  int i;
633  for (i = 0; i < RTR_MAX_HOSTS; i++) {
634  if (!rtr_host[i].fd) {
635  continue;
636  }
637  const char *proto = "rap";
638  switch (rtr_host[i].proto) {
639  case RTR_PROTOCOL_HTTP: proto = "http"; break;
640  case RTR_PROTOCOL_TCP: proto = "tcp"; break;
641  case RTR_PROTOCOL_UDP: proto = "udp"; break;
642  case RTR_PROTOCOL_RAP: proto = "rap"; break;
643  case RTR_PROTOCOL_UNIX: proto = "unix"; break;
644  }
645  rz_cons_printf("%d fd:%i %s://%s:%i/%s\n",
646  i, (int)rtr_host[i].fd->fd, proto, rtr_host[i].host,
647  rtr_host[i].port, rtr_host[i].file);
648  }
649 }
650 
651 RZ_API void rz_core_rtr_add(RzCore *core, const char *_input) {
652  char *port, input[1024], *file = NULL, *ptr = NULL;
653  int i, timeout, ret;
654  RzSocket *fd;
655 
656  timeout = rz_config_get_i(core->config, "http.timeout");
657  strncpy(input, _input, sizeof(input) - 4);
658  input[sizeof(input) - 4] = '\0';
659 
660  int proto = RTR_PROTOCOL_RAP;
661  char *host = (char *)rz_str_trim_head_ro(input);
662  char *pikaboo = strstr(host, "://");
663  if (pikaboo) {
664  struct {
665  const char *name;
666  int protocol;
667  } uris[7] = {
668  { "tcp", RTR_PROTOCOL_TCP },
669  { "udp", RTR_PROTOCOL_UDP },
670  { "rap", RTR_PROTOCOL_RAP },
671  { "r2p", RTR_PROTOCOL_RAP },
672  { "http", RTR_PROTOCOL_HTTP },
673  { "unix", RTR_PROTOCOL_UNIX },
674  { NULL, 0 }
675  };
676  char *s = rz_str_ndup(input, pikaboo - input);
677  // int nlen = pikaboo - input;
678  for (i = 0; uris[i].name; i++) {
679  if (rz_str_endswith(s, uris[i].name)) {
680  proto = uris[i].protocol;
681  host = pikaboo + 3;
682  break;
683  }
684  }
685  free(s);
686  }
687  if (host) {
688  if (!(ptr = strchr(host, ':'))) {
689  ptr = host;
690  port = "80";
691  } else {
692  *ptr++ = '\0';
693  port = ptr;
694  rz_str_trim(port);
695  }
696  } else {
697  port = NULL;
698  }
699  file = strchr(ptr, '/');
700  if (file) {
701  *file = 0;
702  file = (char *)rz_str_trim_head_ro(file + 1);
703  } else {
704  if (*host == ':' || strstr(host, "://:")) { // listen
705  // it's fine to listen without serving a file
706  } else {
707  file = "cmd/";
708  eprintf("Error: Missing '/'\n");
709  // c:wreturn;
710  }
711  }
712 
713  fd = rz_socket_new(false);
714  if (!fd) {
715  eprintf("Error: Cannot create new socket\n");
716  return;
717  }
718  switch (proto) {
719  case RTR_PROTOCOL_HTTP: {
720  int len;
721  char *uri = rz_str_newf("http://%s:%s/%s", host, port, file);
722  char *str = rz_socket_http_get(uri, NULL, &len);
723  if (!str) {
724  eprintf("Cannot find peer\n");
725  return;
726  }
727  core->num->value = 0;
728  // eprintf ("Connected to: 'http://%s:%s'\n", host, port);
729  free(str);
730  } break;
731  case RTR_PROTOCOL_RAP:
732  if (!rz_socket_connect_tcp(fd, host, port, timeout)) { // TODO: Use rap.ssl
733  eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
735  return;
736  } else {
737  int n = rz_socket_rap_client_open(fd, file, 0);
738  eprintf("opened as fd = %d\n", n);
739  }
740  break;
741  case RTR_PROTOCOL_UNIX:
742  if (!rz_socket_connect_unix(fd, host)) {
743  core->num->value = 1;
744  eprintf("Error: Cannot connect to 'unix://%s'\n", host);
746  return;
747  }
748  core->num->value = 0;
749  eprintf("Connected to: 'unix://%s'\n", host);
750  break;
751  case RTR_PROTOCOL_TCP:
752  if (!rz_socket_connect_tcp(fd, host, port, timeout)) { // TODO: Use rap.ssl
753  core->num->value = 1;
754  eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
756  return;
757  }
758  core->num->value = 0;
759  eprintf("Connected to: %s at port %s\n", host, port);
760  break;
761  case RTR_PROTOCOL_UDP:
762  if (!rz_socket_connect_udp(fd, host, port, timeout)) { // TODO: Use rap.ssl
763  core->num->value = 1;
764  eprintf("Error: Cannot connect to '%s' (%s)\n", host, port);
766  return;
767  }
768  core->num->value = 0;
769  eprintf("Connected to: %s at port %s\n", host, port);
770  break;
771  }
772  ret = core->num->value;
773  for (i = 0; i < RTR_MAX_HOSTS; i++) {
774  if (rtr_host[i].fd) {
775  continue;
776  }
777  rtr_host[i].proto = proto;
778  strncpy(rtr_host[i].host, host, sizeof(rtr_host[i].host) - 1);
779  rtr_host[i].port = rz_num_get(core->num, port);
780  if (!file) {
781  file = "";
782  }
783  strncpy(rtr_host[i].file, file, sizeof(rtr_host[i].file) - 1);
784  rtr_host[i].fd = fd;
785  rtr_n = i;
786  break;
787  }
788  core->num->value = ret;
789  // double free wtf is freed this here? rz_socket_free(fd);
790  // rz_core_rtr_list (core);
791 }
792 
793 RZ_API void rz_core_rtr_remove(RzCore *core, const char *input) {
794  int i;
795 
796  if (IS_DIGIT(input[0])) {
797  i = rz_num_math(core->num, input);
798  if (i >= 0 && i < RTR_MAX_HOSTS) {
800  rtr_host[i].fd = NULL;
801  }
802  } else {
803  for (i = 0; i < RTR_MAX_HOSTS; i++) {
804  if (rtr_host[i].fd) {
806  rtr_host[i].fd = NULL;
807  }
808  }
809  memset(rtr_host, '\0', RTR_MAX_HOSTS * sizeof(RzCoreRtrHost));
810  rtr_n = 0;
811  }
812 }
813 
814 RZ_API void rz_core_rtr_session(RzCore *core, const char *input) {
815  __rtr_shell(core, atoi(input));
816 }
817 
818 static bool rz_core_rtr_rap_run(RzCore *core, const char *input) {
819  char *file = rz_str_newf("rap://%s", input);
820  int flags = RZ_PERM_RW;
821  RzIODesc *fd = rz_io_open_nomap(core->io, file, flags, 0644);
822  if (fd) {
823  if (rz_io_is_listener(core->io)) {
824  if (!rz_core_serve(core, fd)) {
825  rz_cons_singleton()->context->breaked = true;
826  }
828  // avoid double free, we are not the owners of this fd so we can't destroy it
829  // rz_io_desc_free (fd);
830  }
831  } else {
832  rz_cons_singleton()->context->breaked = true;
833  }
834  return !rz_cons_singleton()->context->breaked;
835  // rz_core_cmdf (core, "o rap://%s", input);
836 }
837 
839  if (!rt || !rt->core) {
840  return false;
841  }
842  bool loop = true;
843  while (loop) {
844  loop = rz_atomic_bool_get(rt->loop) &&
845  rz_core_rtr_rap_run(rt->core, rt->input);
846  }
847  return NULL;
848 }
849 
850 RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input) {
851  unsigned int cmd_len = 0;
852  int fd = atoi(input);
853  if (!fd && *input != '0') {
854  fd = -1;
855  }
856  const char *cmd = strchr(rz_str_trim_head_ro(input), ' ');
857  if (cmd) {
858  cmd++;
859  cmd_len = strlen(cmd);
860  }
861  // "=:"
862  if (*input == ':' && !strchr(input + 1, ':')) {
863  void *bed = rz_cons_sleep_begin();
864  rz_core_rtr_rap_run(core, input);
865  rz_cons_sleep_end(bed);
866  return;
867  }
868 
869  if (*input == '&') { // "Rh&" "R&:9090"
870  if (rapthread) {
871  eprintf("RAP Thread is already running\n");
872  eprintf("This is experimental and probably buggy. Use at your own risk\n");
873  } else {
874  // TODO: use tasks
875  RapThread *rap_th = RZ_NEW0(RapThread);
876  if (!rap_th) {
877  RZ_LOG_ERROR("cannot allocate RapThread\n");
878  return;
879  }
880  rap_th->core = core;
881  rap_th->input = strdup(input + 1);
882  rap_th->loop = rz_atomic_bool_new(true);
883 
885  if (!rap_th) {
886  RZ_LOG_ERROR("cannot spawn the RzThread\n");
887  return;
888  }
889  int cpuaff = (int)rz_config_get_i(core->config, "cfg.cpuaffinity");
890  if (cpuaff) {
891  // modify the affinity only when the flag is actually set.
892  rz_th_set_affinity(rapthread, cpuaff);
893  }
894  rz_th_set_name(rapthread, "rapthread");
895  RZ_LOG_WARN("Background rap server started.\n");
896  }
897  return;
898  }
899 
900  if (fd != -1) {
901  if (fd >= 0 && fd < RTR_MAX_HOSTS) {
902  rtr_n = fd;
903  }
904  } else {
905  // XXX
906  cmd = input;
907  }
908 
909  if (!rtr_host[rtr_n].fd) {
910  eprintf("Error: Unknown host\n");
911  core->num->value = 1; // fail
912  return;
913  }
914 
915  if (rtr_host[rtr_n].proto == RTR_PROTOCOL_TCP) {
916  RzCoreRtrHost *rh = &rtr_host[rtr_n];
917  RzSocket *s = rh->fd;
918  if (cmd_len < 1 || cmd_len > 16384) {
919  return;
920  }
922  if (!rz_socket_connect(s, rh->host, sdb_fmt("%d", rh->port), RZ_SOCKET_PROTO_TCP, 0)) {
923  eprintf("Error: Cannot connect to '%s' (%d)\n", rh->host, rh->port);
924  rz_socket_free(s);
925  return;
926  }
927  rz_socket_write(s, (ut8 *)cmd, cmd_len);
928  rz_socket_write(s, "\n", 2);
929  int maxlen = 4096; // rz_read_le32 (blen);
930  char *cmd_output = calloc(1, maxlen + 1);
931  if (!cmd_output) {
932  eprintf("Error: Allocating cmd output\n");
933  return;
934  }
935  (void)rz_socket_read_block(s, (ut8 *)cmd_output, maxlen);
936  // ensure the termination
938  cmd_output[maxlen] = 0;
939  rz_cons_println(cmd_output);
940  free((void *)cmd_output);
941  return;
942  }
943 
944  if (rtr_host[rtr_n].proto == RTR_PROTOCOL_HTTP) {
945  RzCoreRtrHost *rh = &rtr_host[rtr_n];
946  if (cmd_len < 1 || cmd_len > 16384) {
947  return;
948  }
949  int len;
950  char *uri = rz_str_newf("http://%s:%d/cmd/%s", rh->host, rh->port, cmd);
951  char *str = rz_socket_http_get(uri, NULL, &len);
952  if (!str) {
953  eprintf("Cannot find '%s'\n", uri);
954  free(uri);
955  return;
956  }
957  core->num->value = 0;
958  str[len] = 0;
959  rz_cons_print(str);
960  free((void *)str);
961  free((void *)uri);
962  return;
963  }
964 
965  if (rtr_host[rtr_n].proto == RTR_PROTOCOL_RAP) {
966  core->num->value = 0; // that's fine
968  RzSocket *fh = rtr_host[rtr_n].fd;
969  if (!strlen(cmd)) {
970  // just check if we can connect
972  return;
973  }
974  char *cmd_output = rz_socket_rap_client_command(fh, cmd, &core->analysis->coreb);
975  rz_cons_println(cmd_output);
976  free(cmd_output);
977  return;
978  }
979  eprintf("Error: Unknown protocol\n");
980 }
981 
982 // TODO: support len for binary data?
983 RZ_API char *rz_core_rtr_cmds_query(RzCore *core, const char *host, const char *port, const char *cmd) {
984  RzSocket *s = rz_socket_new(0);
985  const int timeout = 0;
986  char *rbuf = NULL;
987  int retries = 6;
988  ut8 buf[1024];
989 
990  for (; retries > 0; rz_sys_usleep(10 * 1000)) {
991  if (rz_socket_connect(s, host, port, RZ_SOCKET_PROTO_TCP, timeout)) {
992  break;
993  }
994  retries--;
995  }
996  if (retries > 0) {
997  rbuf = strdup("");
998  rz_socket_write(s, (void *)cmd, strlen(cmd));
999  // rz_socket_write (s, "px\n", 3);
1000  for (;;) {
1001  int ret = rz_socket_read(s, buf, sizeof(buf));
1002  if (ret < 1) {
1003  break;
1004  }
1005  buf[ret] = 0;
1006  rbuf = rz_str_append(rbuf, (const char *)buf);
1007  }
1008  } else {
1009  eprintf("Cannot connect\n");
1010  }
1011  rz_socket_free(s);
1012  return rbuf;
1013 }
1014 
1021  rz_return_val_if_fail(core, false);
1023  return rtr_host;
1024 }
1025 
1026 #if HAVE_LIBUV
1027 
1028 typedef struct rtr_cmds_context_t {
1029  uv_tcp_t server;
1030  RzPVector clients;
1031  void *bed;
1032 } rtr_cmds_context;
1033 
1034 typedef struct rtr_cmds_client_context_t {
1035  RzCore *core;
1036  char buf[4096];
1037  char *res;
1038  size_t len;
1039  uv_tcp_t *client;
1040 } rtr_cmds_client_context;
1041 
1042 static void rtr_cmds_client_close(uv_tcp_t *client, bool remove) {
1043  uv_loop_t *loop = client->loop;
1044  rtr_cmds_context *context = loop->data;
1045  if (remove) {
1046  size_t i;
1047  for (i = 0; i < rz_pvector_len(&context->clients); i++) {
1048  if (rz_pvector_at(&context->clients, i) == client) {
1049  rz_pvector_remove_at(&context->clients, i);
1050  break;
1051  }
1052  }
1053  }
1054  rtr_cmds_client_context *client_context = client->data;
1055  uv_close((uv_handle_t *)client, (uv_close_cb)free);
1056  free(client_context->res);
1057  free(client_context);
1058 }
1059 
1060 static void rtr_cmds_alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
1061  rtr_cmds_client_context *context = handle->data;
1062  buf->base = context->buf + context->len;
1063  buf->len = sizeof(context->buf) - context->len - 1;
1064 }
1065 
1066 static void rtr_cmds_write(uv_write_t *req, int status) {
1067  rtr_cmds_client_context *context = req->data;
1068 
1069  if (status) {
1070  eprintf("Write error: %s\n", uv_strerror(status));
1071  }
1072 
1073  free(req);
1074  rtr_cmds_client_close(context->client, true);
1075 }
1076 
1077 static void rtr_cmds_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) {
1078  rtr_cmds_context *context = client->loop->data;
1079  rtr_cmds_client_context *client_context = client->data;
1080 
1081  if (nread < 0) {
1082  if (nread != UV_EOF) {
1083  eprintf("Failed to read: %s\n", uv_err_name((int)nread));
1084  }
1085  rtr_cmds_client_close((uv_tcp_t *)client, true);
1086  return;
1087  } else if (nread == 0) {
1088  return;
1089  }
1090 
1091  buf->base[nread] = '\0';
1092  char *end = strchr(buf->base, '\n');
1093  if (!end) {
1094  return;
1095  }
1096  *end = '\0';
1097 
1098  rz_cons_sleep_end(context->bed);
1099  client_context->res = rz_core_cmd_str(client_context->core, (const char *)client_context->buf);
1100  context->bed = rz_cons_sleep_begin();
1101 
1102  if (!client_context->res || !*client_context->res) {
1103  free(client_context->res);
1104  client_context->res = strdup("\n");
1105  }
1106 
1107  if (!client_context->res || (!rz_config_get_i(client_context->core->config, "scr.prompt") && !strcmp((char *)buf, "q!")) ||
1108  !strcmp((char *)buf, ".--")) {
1109  rtr_cmds_client_close((uv_tcp_t *)client, true);
1110  return;
1111  }
1112 
1114  if (req) {
1115  req->data = client_context;
1116  uv_buf_t wrbuf = uv_buf_init(client_context->res, (unsigned int)strlen(client_context->res));
1117  uv_write(req, client, &wrbuf, 1, rtr_cmds_write);
1118  }
1119  uv_read_stop(client);
1120 }
1121 
1122 static void rtr_cmds_new_connection(uv_stream_t *server, int status) {
1123  if (status < 0) {
1124  eprintf("New connection error: %s\n", uv_strerror(status));
1125  return;
1126  }
1127 
1128  rtr_cmds_context *context = server->loop->data;
1129 
1130  uv_tcp_t *client = RZ_NEW(uv_tcp_t);
1131  if (!client) {
1132  return;
1133  }
1134 
1135  uv_tcp_init(server->loop, client);
1136  if (uv_accept(server, (uv_stream_t *)client) == 0) {
1137  rtr_cmds_client_context *client_context = RZ_NEW(rtr_cmds_client_context);
1138  if (!client_context) {
1139  uv_close((uv_handle_t *)client, NULL);
1140  return;
1141  }
1142 
1143  client_context->core = server->data;
1144  client_context->len = 0;
1145  client_context->buf[0] = '\0';
1146  client_context->res = NULL;
1147  client_context->client = client;
1148  client->data = client_context;
1149 
1150  uv_read_start((uv_stream_t *)client, rtr_cmds_alloc_buffer, rtr_cmds_read);
1151 
1152  rz_pvector_push(&context->clients, client);
1153  } else {
1154  uv_close((uv_handle_t *)client, NULL);
1155  }
1156 }
1157 
1158 static void rtr_cmds_stop(uv_async_t *handle) {
1160 
1161  rtr_cmds_context *context = handle->loop->data;
1162 
1163  uv_close((uv_handle_t *)&context->server, NULL);
1164 
1165  void **it;
1166  rz_pvector_foreach (&context->clients, it) {
1167  uv_tcp_t *client = *it;
1168  rtr_cmds_client_close(client, false);
1169  }
1170 }
1171 
1172 static void rtr_cmds_break(uv_async_t *async) {
1174 }
1175 
1176 RZ_API int rz_core_rtr_cmds(RzCore *core, const char *port) {
1177  if (!port || port[0] == '?') {
1178  rz_cons_printf("Usage: .:[tcp-port] run rizin commands for clients\n");
1179  return 0;
1180  }
1181 
1183  if (!loop) {
1184  return 0;
1185  }
1186  uv_loop_init(loop);
1187 
1188  rtr_cmds_context context;
1189  rz_pvector_init(&context.clients, NULL);
1190  loop->data = &context;
1191 
1192  context.server.data = core;
1193  uv_tcp_init(loop, &context.server);
1194 
1195  struct sockaddr_in addr;
1196  bool local = (bool)rz_config_get_i(core->config, "tcp.islocal");
1197  int porti = rz_socket_port_by_name(port);
1198  uv_ip4_addr(local ? "127.0.0.1" : "0.0.0.0", porti, &addr);
1199 
1200  uv_tcp_bind(&context.server, (const struct sockaddr *)&addr, 0);
1201  int r = uv_listen((uv_stream_t *)&context.server, 32, rtr_cmds_new_connection);
1202  if (r) {
1203  eprintf("Failed to listen: %s\n", uv_strerror(r));
1204  goto beach;
1205  }
1206 
1207  uv_async_t stop_async;
1208  uv_async_init(loop, &stop_async, rtr_cmds_stop);
1209 
1210  rz_cons_break_push((RzConsBreak)rtr_cmds_break, &stop_async);
1211  context.bed = rz_cons_sleep_begin();
1215 
1216 beach:
1218  free(loop);
1219  rz_pvector_clear(&context.clients);
1220  return 0;
1221 }
1222 
1223 #else
1224 
1225 RZ_API int rz_core_rtr_cmds(RzCore *core, const char *port) {
1226  unsigned char buf[4097];
1227  RzSocket *ch = NULL;
1228  int i, ret;
1229  char *str;
1230 
1231  if (!port || port[0] == '?') {
1232  rz_cons_printf("Usage: .:[tcp-port] run rizin commands for clients\n");
1233  return false;
1234  }
1235 
1236  RzSocket *s = rz_socket_new(0);
1237  s->local = rz_config_get_i(core->config, "tcp.islocal");
1238 
1239  if (!rz_socket_listen(s, port, NULL)) {
1240  eprintf("Error listening on port %s\n", port);
1241  rz_socket_free(s);
1242  return false;
1243  }
1244 
1245  eprintf("Listening for commands on port %s\n", port);
1246  listenport = port;
1247  rz_cons_break_push((RzConsBreak)rz_core_rtr_http_stop, core);
1248  for (;;) {
1249  if (rz_cons_is_breaked()) {
1250  break;
1251  }
1252  void *bed = rz_cons_sleep_begin();
1253  ch = rz_socket_accept(s);
1254  buf[0] = 0;
1255  ret = rz_socket_read(ch, buf, sizeof(buf) - 1);
1256  rz_cons_sleep_end(bed);
1257  if (ret > 0) {
1258  buf[ret] = 0;
1259  for (i = 0; buf[i]; i++) {
1260  if (buf[i] == '\n') {
1261  buf[i] = buf[i + 1] ? ';' : '\0';
1262  }
1263  }
1264  if ((!rz_config_get_i(core->config, "scr.prompt") &&
1265  !strcmp((char *)buf, "q!")) ||
1266  !strcmp((char *)buf, ".--")) {
1267  rz_socket_close(ch);
1268  break;
1269  }
1270  str = rz_core_cmd_str(core, (const char *)buf);
1271  bed = rz_cons_sleep_begin();
1272  if (str && *str) {
1273  rz_socket_write(ch, str, strlen(str));
1274  } else {
1275  rz_socket_write(ch, "\n", 1);
1276  }
1277  rz_cons_sleep_end(bed);
1278  free(str);
1279  }
1280  rz_socket_close(ch);
1281  rz_socket_free(ch);
1282  ch = NULL;
1283  }
1285  rz_socket_free(s);
1286  rz_socket_free(ch);
1287  return 0;
1288 }
1289 
1290 #endif
size_t len
Definition: 6502dis.c:15
#define T(op)
#define PFMT32x
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
ut16 val
Definition: armass64_const.h:6
static mcore_handle handle
Definition: asm_mcore.c:8
static ut64 baddr(RzBinFile *bf)
Definition: bin_any.c:58
const char * desc
Definition: bin_vsf.c:19
#define local
Definition: blast.c:36
int bits(struct state *s, int need)
Definition: blast.c:72
FILE * fh
Definition: cabinfo.c:52
RZ_API void rz_core_file_reopen_debug(RzCore *core, const char *args)
Definition: cfile.c:269
RZ_API RZ_BORROW RzCoreFile * rz_core_file_open(RZ_NONNULL RzCore *r, RZ_NONNULL const char *file, int flags, ut64 loadaddr)
Tries to open the file as is, otherwise tries as is a compilation of files.
Definition: cfile.c:1182
RZ_API bool rz_core_bin_load(RZ_NONNULL RzCore *r, RZ_NULLABLE const char *filenameuri, ut64 baddr)
Definition: cfile.c:942
RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log)
Definition: cmd.c:5328
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
Definition: cmd.c:5513
static io_buf out_buf
Definition: coder.c:40
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API bool rz_cons_enable_mouse(const bool enable)
Definition: cons.c:500
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API void * rz_cons_sleep_begin(void)
Definition: cons.c:443
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_show_cursor(int cursor)
Definition: cons.c:1581
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API void rz_cons_sleep_end(void *user)
Definition: cons.c:450
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_arch arch
Definition: cstool.c:13
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint16_t ut16
uint32_t ut32
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write)
Definition: dreg.c:9
struct @667 g
checking print the parsed form of the magic use in n conjunction with m to debug a new magic file n before installing it n output MIME type special files
Definition: file_opts.h:46
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
static const char * commands[]
Definition: h8300_disas.c:21
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
vsnprintf
Definition: kernel.h:366
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
bool gdbr_set_architecture(libgdbr_t *g, int arch, int bits)
Function initializes the architecture of the gdbsession.
Definition: libgdbr.c:52
int gdbr_cleanup(libgdbr_t *g)
frees all buffers and cleans the libgdbr instance stuff
Definition: libgdbr.c:146
int gdbr_init(libgdbr_t *g, bool is_server)
Function initializes the libgdbr lib.
Definition: libgdbr.c:9
RZ_API bool rz_core_serve(RzCore *core, RzIODesc *file)
Definition: core.c:2904
RZ_API ut64 rz_debug_get_baddr(RzDebug *dbg, const char *file)
Definition: debug.c:1682
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API RZ_OWN void * rz_th_get_user(RZ_NONNULL RzThread *th)
Returns user pointer of thread.
Definition: thread.c:263
RZ_API bool rz_th_set_affinity(RZ_NONNULL RzThread *th, int cpuid)
Sets the thread cpu affinity.
Definition: thread.c:122
RZ_API RZ_OWN RzThread * rz_th_new(RZ_NONNULL RzThreadFunction function, RZ_NULLABLE void *user)
Creates and starts a new thread.
Definition: thread.c:198
RZ_API bool rz_th_wait(RZ_NONNULL RzThread *th)
Awaits indefinetely for a thread to join.
Definition: thread.c:231
RZ_API bool rz_th_set_name(RZ_NONNULL RzThread *th, RZ_NONNULL const char *name)
Sets the name of the thread.
Definition: thread.c:44
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t alarm
Definition: sflib.h:55
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause access
Definition: sflib.h:64
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
char * dest
Definition: lz4.h:697
int args
Definition: mipsasm.c:18
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
const char * name
Definition: op.c:541
int off
Definition: pal.c:13
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API void rz_core_rtr_session(RzCore *core, const char *input)
Definition: rtr.c:814
RZ_API void rz_core_rtr_list(RzCore *core)
Definition: rtr.c:631
static const char * listenport
Definition: rtr.c:30
static void * rz_core_rtr_rap_thread(RapThread *rt)
Definition: rtr.c:838
RZ_API int rz_core_rtr_http_stop(RzCore *u)
Definition: rtr.c:110
RZ_API void rz_core_rtr_add(RzCore *core, const char *_input)
Definition: rtr.c:651
static int write_reg_val(char *buf, ut64 sz, ut64 reg, int regsize, bool bigendian)
Definition: rtr.c:171
RZ_API char * rz_core_rtr_cmds_query(RzCore *core, const char *host, const char *port, const char *cmd)
Definition: rtr.c:983
RZ_API int rz_core_rtr_gdb(RzCore *core, int launch, const char *path)
Definition: rtr.c:571
static void http_logf(RzCore *core, const char *fmt,...)
Definition: rtr.c:61
static char * rtr_dir_files(const char *path)
Definition: rtr.c:131
RZ_API bool rz_core_rtr_init(RZ_NONNULL RzCore *core)
Allocates core rtr structure.
Definition: rtr.c:1020
static RzThread * rapthread
Definition: rtr.c:29
static RzSocket * s
Definition: rtr.c:28
static int rz_core_rtr_gdb_run(RzCore *core, int launch, const char *path)
Definition: rtr.c:480
#define rtr_host
Definition: rtr.c:26
static int rz_core_rtr_gdb_cb(libgdbr_t *g, void *core_ptr, const char *cmd, char *out_buf, size_t max_len)
Definition: rtr.c:278
static int write_big_reg(char *buf, ut64 sz, const utX *val, int regsize, bool bigendian)
Definition: rtr.c:194
static void activateDieTime(RzCore *core)
Definition: rtr.c:156
#define rtr_n
Definition: rtr.c:25
RZ_API void rz_core_rtr_remove(RzCore *core, const char *input)
Definition: rtr.c:793
static char * rtrcmd(TextLog T, const char *str)
Definition: rtr.c:81
static int swap_big_regs(char *dest, ut64 sz, const char *src, int regsz)
Definition: rtr.c:231
RZ_API void rz_core_wait(RzCore *core)
Definition: rtr.c:52
static bool rz_core_rtr_rap_run(RzCore *core, const char *input)
Definition: rtr.c:818
RZ_API int rz_core_rtr_cmds(RzCore *core, const char *port)
Definition: rtr.c:1225
RZ_API void rz_core_rtr_pushout(RzCore *core, const char *input)
Definition: rtr.c:582
static void showcursor(RzCore *core, int x)
Definition: rtr.c:100
RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input)
Definition: rtr.c:850
static void __rtr_shell(RzCore *core, int nth)
Definition: rtr_shell.c:182
RZ_API ut64 rz_reg_get_value_big(RzReg *reg, RzRegItem *item, utX *val)
Definition: rvalue.c:60
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RTR_PROTOCOL_UNIX
Definition: rz_core.h:92
#define RTR_PROTOCOL_UDP
Definition: rz_core.h:90
#define RTR_MAX_HOSTS
Definition: rz_core.h:94
#define RTR_PROTOCOL_TCP
Definition: rz_core.h:89
#define RTR_PROTOCOL_RAP
Definition: rz_core.h:88
#define RTR_PROTOCOL_HTTP
Definition: rz_core.h:91
@ RZ_DEBUG_REASON_STEP
Definition: rz_debug.h:98
@ RZ_DEBUG_REASON_BREAKPOINT
Definition: rz_debug.h:94
@ RZ_DEBUG_REASON_TRAP
Definition: rz_debug.h:111
static ut32 rz_swap_ut32(ut32 val)
Definition: rz_endian.h:580
static ut16 rz_swap_ut16(ut16 val)
Definition: rz_endian.h:571
static ut64 rz_swap_ut64(ut64 val)
Definition: rz_endian.h:590
RZ_API bool rz_file_dump(const char *file, const ut8 *buf, int len, bool append)
Definition: file.c:838
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
RZ_API RzIODesc * rz_io_desc_get(RzIO *io, int fd)
Definition: io_desc.c:73
RZ_API bool rz_io_is_listener(RzIO *io)
Definition: io.c:404
RZ_API RzIODesc * rz_io_open_nomap(RzIO *io, const char *uri, int flags, int mode)
Definition: io.c:145
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
RZ_API char * rz_socket_rap_client_command(RzSocket *s, const char *cmd, RzCoreBind *c)
RZ_API int rz_socket_close(RzSocket *s)
Definition: socket.c:419
#define rz_socket_connect_unix(a, b)
Definition: rz_socket.h:104
RZ_API int rz_socket_read_block(RzSocket *s, unsigned char *buf, int len)
Definition: socket.c:808
RZ_API int rz_socket_rap_client_open(RzSocket *s, const char *file, int rw)
RZ_API int rz_socket_port_by_name(const char *name)
Definition: socket.c:469
RZ_API RzSocket * rz_socket_accept(RzSocket *s)
Definition: socket.c:582
RZ_API void rz_socket_http_server_set_breaked(bool *b)
RZ_API bool rz_socket_listen(RzSocket *s, const char *port, const char *certfile)
Definition: socket.c:474
#define rz_socket_connect_tcp(a, b, c, d)
Definition: rz_socket.h:99
RZ_API void RZ_API int rz_socket_read(RzSocket *s, ut8 *read, int len)
Definition: socket.c:783
RZ_API bool rz_socket_connect(RzSocket *s, const char *host, const char *port, int proto, unsigned int timeout)
Definition: socket.c:257
RZ_API char * rz_socket_http_get(const char *url, int *code, int *rlen)
Definition: socket_http.c:287
#define RZ_SOCKET_PROTO_TCP
Definition: rz_socket.h:87
RZ_API RzSocket * rz_socket_new(bool is_ssl)
Definition: socket.c:179
RZ_API int rz_socket_free(RzSocket *s)
Definition: socket.c:453
#define rz_socket_connect_udp(a, b, c, d)
Definition: rz_socket.h:100
RZ_API int rz_socket_write(RzSocket *s, void *buf, int len)
Definition: socket.c:724
RZ_API char * rz_str_uri_encode(const char *buf)
Definition: str.c:2860
RZ_API char * rz_str_appendf(char *ptr, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
RZ_API RzList * rz_sys_dir(const char *path)
Definition: sys.c:216
RZ_API int rz_sys_usleep(int usecs)
Sleep for usecs microseconds.
Definition: sys.c:317
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
RZ_API int rz_sys_arch_id(const char *arch)
Definition: sys.c:788
void *(* RzThreadFunction)(void *user)
Definition: rz_th.h:28
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RW
Definition: rz_types.h:96
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
RZ_API void * rz_pvector_remove_at(RzPVector *vec, size_t index)
Definition: vector.c:355
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
RZ_API void rz_pvector_clear(RzPVector *vec)
Definition: vector.c:326
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
int gdbr_server_serve(libgdbr_t *g, gdbr_server_cmd_cb cmd_cb, void *core_ptr)
Definition: core.c:495
#define isspace(c)
Definition: safe-ctype.h:141
static struct sockaddr static addrlen listen
Definition: sfsocketcall.h:116
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static int
Definition: sfsocketcall.h:114
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
int ssize_t
Definition: sftypes.h:39
Definition: rtr.c:46
RzAtomicBool * loop
Definition: rtr.c:49
RzCore * core
Definition: rtr.c:47
char * input
Definition: rtr.c:48
Definition: rtr.c:40
const char * host
Definition: rtr.c:41
const char * file
Definition: rtr.c:43
const char * port
Definition: rtr.c:42
Definition: gzappend.c:170
Definition: arch.h:13
char name[32]
Definition: arch.h:14
uint64_t size
Definition: arch.h:16
Definition: z80asm.h:102
RzCoreBind coreb
Definition: rz_analysis.h:580
RzConsContext * context
Definition: rz_cons.h:502
RzSocket * fd
Definition: rtr.c:37
char host[512]
Definition: rtr.c:34
bool vmode
Definition: rz_core.h:309
RzAnalysis * analysis
Definition: rz_core.h:322
RzDebug * dbg
Definition: rz_core.h:329
int gdbserver_up
Definition: rz_core.h:356
RzIO * io
Definition: rz_core.h:313
RzNum * num
Definition: rz_core.h:316
RzCoreFile * file
Definition: rz_core.h:314
RzConfig * config
Definition: rz_core.h:300
RzList *(* threads)(RzDebug *dbg, int pid)
Definition: rz_debug.h:375
RzDebugReason reason
Definition: rz_debug.h:276
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295
RzReg * reg
Definition: rz_debug.h:286
ut64 value
Definition: rz_num.h:63
Definition: thread.h:84
Definition: uv.h:844
Definition: unix.h:123
Definition: uv.h:1780
void * data
Definition: uv.h:1782
Definition: uv.h:547
Definition: uv.h:525
uv_loop_t * loop
Definition: main.c:7
uv_async_t async
Definition: main.c:8
uv_timer_t timeout
Definition: main.c:9
ut64 maxlen
Definition: core.c:76
#define bool
Definition: sysdefs.h:146
RZ_API RZ_OWN RzAtomicBool * rz_atomic_bool_new(bool value)
Initialize a thread safe bool type container.
Definition: thread_types.c:24
RZ_API bool rz_atomic_bool_get(RZ_NONNULL RzAtomicBool *tbool)
Gets the current value hold by the RzAtomicBool structure.
Definition: thread_types.c:54
RZ_API void rz_atomic_bool_set(RZ_NONNULL RzAtomicBool *tbool, bool value)
Sets the value int the RzAtomicBool structure.
Definition: thread_types.c:68
UV_EXTERN int uv_ip4_addr(const char *ip, int port, struct sockaddr_in *addr)
Definition: uv-common.c:221
@ UV_RUN_DEFAULT
Definition: uv.h:255
UV_EXTERN int uv_write(uv_write_t *req, uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
Definition: stream.c:1492
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
UV_EXTERN int uv_read_stop(uv_stream_t *)
Definition: stream.c:1590
UV_EXTERN int uv_read_start(uv_stream_t *, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Definition: stream.c:1555
UV_EXTERN int uv_listen(uv_stream_t *stream, int backlog, uv_connection_cb cb)
Definition: stream.c:656
UV_EXTERN int uv_loop_init(uv_loop_t *loop)
Definition: loop.c:30
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: core.c:365
UV_EXTERN const char * uv_err_name(int err)
Definition: uv-common.c:189
UV_EXTERN int uv_tcp_bind(uv_tcp_t *handle, const struct sockaddr *addr, unsigned int flags)
Definition: uv-common.c:277
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: core.c:108
UV_EXTERN const char * uv_strerror(int err)
Definition: uv-common.c:212
UV_EXTERN int uv_accept(uv_stream_t *server, uv_stream_t *client)
Definition: stream.c:591
UV_EXTERN int uv_tcp_init(uv_loop_t *, uv_tcp_t *handle)
Definition: tcp.c:143
UV_EXTERN int uv_async_init(uv_loop_t *, uv_async_t *async, uv_async_cb async_cb)
Definition: async.c:45
UV_EXTERN int uv_async_send(uv_async_t *async)
Definition: async.c:63
UV_EXTERN int uv_loop_close(uv_loop_t *loop)
Definition: uv-common.c:791
void(* uv_close_cb)(uv_handle_t *handle)
Definition: uv.h:319
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static const z80_opcode fd[]
Definition: z80_tab.h:997
static int file
Definition: z80asm.c:58
static int addr
Definition: z80asm.c:58
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)