Rizin
unix-like reverse engineering framework and cli tools
debug.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2018 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2009-2018 jduck <github.jdrake@qoop.org>
3 // SPDX-FileCopyrightText: 2009-2018 LemonBoy <thatlemon@gmail.com>
4 // SPDX-FileCopyrightText: 2009-2018 saucec0de
5 // SPDX-License-Identifier: LGPL-3.0-only
6 
7 #include <rz_debug.h>
8 #include <rz_drx.h>
9 #include <rz_core.h>
10 #include <rz_windows.h>
11 #include <signal.h>
12 
13 RZ_LIB_VERSION(rz_debug);
14 
15 // Size of the lookahead buffers used in rz_debug functions
16 #define DBG_BUF_SIZE 512
17 
19  if (!dbg || !dbg->cur || !dbg->cur->info) {
20  return NULL;
21  }
22  if (dbg->pid < 0) {
23  return NULL;
24  }
25  return dbg->cur->info(dbg, arg);
26 }
27 
29  if (rdi) {
30  free(rdi->cwd);
31  free(rdi->exe);
32  free(rdi->cmdline);
33  free(rdi->libname);
34  free(rdi->usr);
35  free(rdi);
36  }
37 }
38 
40  /* update all bp->addr if they are named bps */
41  RzBreakpointItem *bp;
43  rz_list_foreach (dbg->bp->bps, iter, bp) {
44  if (bp->expr) {
45  bp->addr = dbg->corebind.numGet(dbg->corebind.core, bp->expr);
46  }
47  }
48 }
49 
51  if (dbg && dbg->cur && dbg->cur->drx) {
52  return dbg->cur->drx(dbg, 0, addr, 0, 0, 0, DRX_API_GET_BP);
53  }
54  return -1;
55 }
56 
57 /*
58  * Recoiling after a breakpoint has two stages:
59  * 1. remove the breakpoint and fix the program counter.
60  * 2. on resume, single step once and then replace the breakpoint.
61  *
62  * Thus, we have two functions to handle these situations.
63  * rz_debug_bp_hit handles stage 1.
64  * rz_debug_recoil handles stage 2.
65  */
68 
69  if (!pb) {
70  eprintf("BreakpointItem is NULL!\n");
71  return false;
72  }
73  /* initialize the output parameter */
74  *pb = NULL;
75 
76  /* if we are tracing, update the tracing data */
77  if (dbg->trace->enabled) {
79  }
80 
81  /* remove all sw breakpoints for now. we'll set them back in stage 2
82  *
83  * this is necessary because while stopped we don't want any breakpoints in
84  * the code messing up our analysis.
85  */
87  if (!rz_bp_restore(dbg->bp, false)) { // unset sw breakpoints
88  return false;
89  }
90 
91  /* if we are recoiling, tell rz_debug_step that we ignored a breakpoint
92  * event */
94  dbg->reason.bp_addr = 0;
95  return true;
96  }
97 
98  /* The MIPS ptrace has a different behaviour */
99 #if __mips__
100  /* see if we really have a breakpoint here... */
101  b = rz_bp_get_at(dbg->bp, pc);
102  if (!b) { /* we don't. nothing left to do */
103  return true;
104  }
105 #else
106  /* see if we really have a breakpoint here... */
107  if (!dbg->pc_at_bp_set) {
109  if (!b) { /* we don't. nothing left to do */
110  /* Some targets set pc to breakpoint */
111  b = rz_bp_get_at(dbg->bp, pc);
112  if (!b) {
113  /* handle the case of hw breakpoints - notify the user */
114  int drx_reg_idx = rz_debug_drx_at(dbg, pc);
115  if (drx_reg_idx != -1) {
116  eprintf("hit hardware breakpoint %d at: %" PFMT64x "\n",
117  drx_reg_idx, pc);
118  }
119  /* Couldn't find the break point. Nothing more to do... */
120  return true;
121  } else {
122  dbg->pc_at_bp_set = true;
123  dbg->pc_at_bp = true;
124  }
125  } else {
126  dbg->pc_at_bp_set = true;
127  dbg->pc_at_bp = false;
128  }
129  }
130 
131  if (!dbg->pc_at_bp_set) {
132  eprintf("failed to determine position of pc after breakpoint");
133  }
134 
135  int pc_off = 0;
136  if (dbg->pc_at_bp) {
137  b = rz_bp_get_at(dbg->bp, pc);
138  } else {
140  if (b) {
141  pc_off = b->size;
142  }
143  }
144 
145  if (!b) {
146  return true;
147  }
148 
150  if (!b) { /* we don't. nothing left to do */
151  /* Some targets set pc to breakpoint */
152  b = rz_bp_get_at(dbg->bp, pc);
153  if (!b) {
154  return true;
155  }
156  pc_off = 0;
157  }
158 
159  /* set the pc value back */
160  if (pc_off) {
161  pc -= pc_off;
162  if (!rz_reg_set_value(dbg->reg, pc_ri, pc)) {
163  eprintf("failed to set PC!\n");
164  return false;
165  }
166  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, true)) {
167  eprintf("cannot set registers!\n");
168  return false;
169  }
170  }
171 #endif
172 
173  *pb = b;
174 
175  /* if we are on a software stepping breakpoint, we hide what is going on... */
176  if (b->swstep) {
177  dbg->reason.bp_addr = 0;
178  return true;
179  }
180 
181  /* setup our stage 2 */
182  dbg->reason.bp_addr = b->addr;
183 
184  /* inform the user of what happened */
185  if (dbg->hitinfo) {
186  eprintf("hit %spoint at: 0x%" PFMT64x "\n",
187  b->trace ? "trace" : "break", pc);
188  }
189 
190  /* now that we've cleaned up after the breakpoint, call the other
191  * potential breakpoint handlers
192  */
193  if (dbg->corebind.core && dbg->corebind.bphit) {
195  }
196  return true;
197 }
198 
199 /* enable all software breakpoints */
201  /* restore all sw breakpoints. we are about to step/continue so these need
202  * to be in place. */
203  if (!rz_bp_restore(dbg->bp, true)) {
204  return false;
205  }
206  /* done recoiling... */
208  return true;
209 }
210 
211 /*
212  * replace breakpoints before we continue execution
213  *
214  * this is called from rz_debug_step_hard or rz_debug_continue_kill
215  *
216  * this is a trick process because of breakpoints/tracepoints.
217  *
218  * if a breakpoint was just hit, we need step over that instruction before
219  * allowing the caller to proceed as desired.
220  *
221  * if the user wants to step, the single step here does the job.
222  */
224  /* if bp_addr is not set, we must not have actually hit a breakpoint */
225  if (!dbg->reason.bp_addr) {
226  return rz_debug_bps_enable(dbg);
227  }
228 
229  /* don't do anything if we already are recoiling */
231  /* the first time recoil is called with swstep, we just need to
232  * look up the bp and step past it.
233  * the second time it's called, the new sw breakpoint should exist
234  * so we just restore all except what we originally hit and reset.
235  */
236  if (dbg->swstep) {
237  if (!rz_bp_restore_except(dbg->bp, true, dbg->reason.bp_addr)) {
238  return false;
239  }
240  return true;
241  }
242 
243  /* otherwise, avoid recursion */
244  return true;
245  }
246 
247  /* we have entered recoil! */
248  dbg->recoil_mode = rc_mode;
249 
250  /* step over the place with the breakpoint and let the caller resume */
251  if (rz_debug_step(dbg, 1) != 1) {
252  return false;
253  }
254 
255  /* when stepping away from a breakpoint during recoil in stepping mode,
256  * the rz_debug_bp_hit function tells us that it was called
257  * innapropriately by setting bp_addr back to zero. however, recoil_mode
258  * is still set. we use this condition to know not to proceed but
259  * pretend as if we had.
260  */
262  return true;
263  }
264  dbg->reason.bp_addr = 0;
265 
266  return rz_debug_bps_enable(dbg);
267 }
268 
269 /* add a breakpoint with some typical values */
270 RZ_API RZ_BORROW RzBreakpointItem *rz_debug_bp_add(RZ_NONNULL RzDebug *dbg, ut64 addr, int hw, bool watch, int rw, RZ_NULLABLE const char *module, st64 m_delta) {
272  int bpsz = rz_bp_size_at(dbg->bp, addr);
273  RzBreakpointItem *bpi;
274  const char *module_name = module;
275  RzListIter *iter;
276  RzDebugMap *map;
277  if (!addr && module) {
278  bool detect_module, valid = false;
279  int perm;
280 
281  if (m_delta) {
282  detect_module = false;
284  rz_list_foreach (list, iter, map) {
285  if (strstr(map->file, module)) {
286  addr = map->addr + m_delta;
287  module_name = map->file;
288  break;
289  }
290  }
292  } else {
293  // module holds the address
295  if (!addr) {
296  return NULL;
297  }
298  detect_module = true;
299  }
301  rz_list_foreach (dbg->maps, iter, map) {
302  if (addr >= map->addr && addr < map->addr_end) {
303  valid = true;
304  if (detect_module) {
305  module_name = map->file;
306  m_delta = addr - map->addr;
307  }
308  perm = ((map->perm & 1) << 2) | (map->perm & 2) | ((map->perm & 4) >> 2);
309  if (!(perm & RZ_PERM_X)) {
310  eprintf("WARNING: setting bp within mapped memory without exec perm\n");
311  }
312  break;
313  }
314  }
315  if (!valid) {
316  eprintf("WARNING: module's base addr + delta is not a valid address\n");
317  return NULL;
318  }
319  }
320  if (!module) {
321  // express db breakpoints as dbm due to ASLR when saving into project
323  rz_list_foreach (dbg->maps, iter, map) {
324  if (addr >= map->addr && addr < map->addr_end) {
325  module_name = map->file;
326  m_delta = addr - map->addr;
327  break;
328  }
329  }
330  }
331  if (watch) {
332  hw = 1; // XXX
333  bpi = rz_bp_watch_add(dbg->bp, addr, bpsz, hw, rw);
334  } else {
335  bpi = hw
336  ? rz_bp_add_hw(dbg->bp, addr, bpsz, RZ_PERM_X)
337  : rz_bp_add_sw(dbg->bp, addr, bpsz, RZ_PERM_X);
338  }
339  if (bpi) {
340  if (module_name) {
341  bpi->module_name = strdup(module_name);
342  bpi->name = rz_str_newf("%s+0x%" PFMT64x, module_name, m_delta);
343  }
344  bpi->module_delta = m_delta;
345  }
346  return bpi;
347 }
348 
349 static const char *rz_debug_str_callback(RzNum *userptr, ut64 off, int *ok) {
350  // RzDebug *dbg = (RzDebug *)userptr;
351  eprintf("rz_debug_str_callback has been called. this should not happen\n");
352  return NULL;
353 }
354 
355 void free_tracenodes_kv(HtUPKv *kv) {
356  free(kv->value);
357 }
358 
360  rz_return_val_if_fail(bp_ctx, NULL);
362  if (!dbg) {
363  return NULL;
364  }
365  // RZ_SYS_ARCH
367  dbg->bits = RZ_SYS_BITS;
368  dbg->trace_forks = 1;
369  dbg->forked_pid = -1;
370  dbg->main_pid = -1;
371  dbg->n_threads = 0;
372  dbg->trace_clone = 0;
373  dbg->egg = rz_egg_new();
375  dbg->trace_aftersyscall = true;
376  dbg->follow_child = false;
377  RZ_FREE(dbg->btalgo);
378  dbg->trace_execs = 0;
379  dbg->analysis = NULL;
380  dbg->pid = -1;
381  dbg->tid = -1;
382  dbg->tree = rz_tree_new();
383  dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL);
384  dbg->swstep = 0;
385  dbg->stop_all_threads = false;
387  dbg->cb_printf = (void *)printf;
388  dbg->reg = rz_reg_new();
390  dbg->cur = NULL;
391  dbg->plugin_data = NULL;
392  dbg->threads = NULL;
393  dbg->hitinfo = 1;
394  /* TODO: needs a redesign? */
397  dbg->q_regs = NULL;
398  dbg->call_frames = NULL;
399  dbg->main_arena_resolved = false;
400  dbg->glibc_version = 231; /* default version ubuntu 20 */
402  dbg->bp = rz_bp_new(bp_ctx);
404  dbg->bp->iob.init = false;
405  dbg->bp->baddr = 0;
407  dbg->hash = rz_hash_new();
408  return dbg;
409 }
410 
412  ht_up_free(dbg->tracenodes);
413  dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL);
414 }
415 
417  if (dbg) {
419  rz_bp_free(dbg->bp);
420  free(dbg->snap_path);
424  rz_num_free(dbg->num);
425  sdb_free(dbg->sgnls);
427  ht_up_free(dbg->tracenodes);
430  free(dbg->btalgo);
434  dbg->trace = NULL;
435  rz_egg_free(dbg->egg);
436  rz_reg_free(dbg->reg);
437  free(dbg->arch);
438  free(dbg->glob_libs);
439  free(dbg->glob_unlibs);
440  free(dbg);
441  }
442  return NULL;
443 }
444 
446  int ret = false;
447  if (dbg && dbg->cur && dbg->cur->attach) {
448  ret = dbg->cur->attach(dbg, pid);
449  if (ret != -1) {
450  dbg->reason.type = RZ_DEBUG_REASON_NONE; // after a successful attach, the process is not dead
451  rz_debug_select(dbg, pid, ret); // dbg->pid, dbg->tid);
452  }
453  }
454  return ret;
455 }
456 
457 /* stop execution of child process */
459  if (dbg && dbg->cur && dbg->cur->stop) {
460  return dbg->cur->stop(dbg);
461  }
462  return false;
463 }
464 
465 RZ_API bool rz_debug_set_arch(RzDebug *dbg, const char *arch, int bits) {
466  if (arch && dbg && dbg->cur) {
467  switch (bits) {
468  case 16:
469  if (dbg->cur->bits & RZ_SYS_BITS_16) {
471  }
472  break;
473  case 27:
474  if (dbg->cur->bits == 27) {
475  dbg->bits = 27;
476  }
477  break;
478  case 32:
479  if (dbg->cur->bits & RZ_SYS_BITS_32) {
481  }
482  break;
483  case 64:
485  break;
486  }
487  if (!dbg->cur->bits) {
488  dbg->bits = dbg->cur->bits;
489  } else if (!(dbg->cur->bits & dbg->bits)) {
491  if (!dbg->bits) {
493  }
494  if (!dbg->bits) {
496  }
497  }
498  free(dbg->arch);
499  dbg->arch = strdup(arch);
500  return true;
501  }
502  return false;
503 }
504 
505 /*
506  * Save 4096 bytes from %esp
507  * TODO: Add support for reverse stack architectures
508  * Also known as rz_debug_inject()
509  */
510 RZ_API ut64 rz_debug_execute(RzDebug *dbg, const ut8 *buf, int len, int restore) {
511  int orig_sz;
512  ut8 stackbackup[4096];
513  ut8 *backup, *orig = NULL;
514  RzRegItem *ri, *risp, *ripc;
515  ut64 rsp, rpc, ra0 = 0LL;
516  if (rz_debug_is_dead(dbg)) {
517  return false;
518  }
521  if (ripc) {
523  orig = rz_reg_get_bytes(dbg->reg, RZ_REG_TYPE_ANY, &orig_sz);
524  if (!orig) {
525  eprintf("Cannot get register arena bytes\n");
526  return 0LL;
527  }
528  rpc = rz_reg_get_value(dbg->reg, ripc);
529  rsp = rz_reg_get_value(dbg->reg, risp);
530 
531  backup = malloc(len);
532  if (!backup) {
533  free(orig);
534  return 0LL;
535  }
536  dbg->iob.read_at(dbg->iob.io, rpc, backup, len);
537  dbg->iob.read_at(dbg->iob.io, rsp, stackbackup, len);
538 
539  rz_bp_add_sw(dbg->bp, rpc + len, 0, RZ_PERM_X);
540 
541  /* execute code here */
542  dbg->iob.write_at(dbg->iob.io, rpc, buf, len);
543  // rz_bp_add_sw (dbg->bp, rpc+len, 4, RZ_PERM_X);
545  // rz_bp_del (dbg->bp, rpc+len);
546  /* TODO: check if stopped in breakpoint or not */
547 
548  rz_bp_del(dbg->bp, rpc + len);
549  dbg->iob.write_at(dbg->iob.io, rpc, backup, len);
550  if (restore) {
551  dbg->iob.write_at(dbg->iob.io, rsp, stackbackup, len);
552  }
553 
556  ra0 = rz_reg_get_value(dbg->reg, ri);
557  if (restore) {
558  rz_reg_read_regs(dbg->reg, orig, orig_sz);
559  } else {
560  rz_reg_set_value(dbg->reg, ripc, rpc);
561  }
563  free(backup);
564  free(orig);
565  eprintf("ra0=0x%08" PFMT64x "\n", ra0);
566  } else {
567  eprintf("rz_debug_execute: Cannot get program counter\n");
568  }
569  return (ra0);
570 }
571 
572 RZ_API int rz_debug_startv(struct rz_debug_t *dbg, int argc, char **argv) {
573  /* TODO : rz_debug_startv unimplemented */
574  return false;
575 }
576 
577 RZ_API int rz_debug_start(RzDebug *dbg, const char *cmd) {
578  /* TODO: this argc/argv parser is done in rz_io */
579  // TODO: parse cmd and generate argc and argv
580  return false;
581 }
582 
584  int ret = 0;
585  if (dbg->cur && dbg->cur->detach) {
586  ret = dbg->cur->detach(dbg, pid);
587  if (dbg->pid == pid) {
588  dbg->pid = -1;
589  dbg->tid = -1;
590  }
591  }
592  return ret;
593 }
594 
595 RZ_API bool rz_debug_select(RzDebug *dbg, int pid, int tid) {
596  ut64 pc = 0;
597  int prev_pid = dbg->pid;
598  int prev_tid = dbg->tid;
599 
600  if (pid < 0) {
601  return false;
602  }
603  if (tid < 0) {
604  tid = pid;
605  }
606 
607  if ((pid != dbg->pid || tid != dbg->tid) && dbg->verbose) {
608  eprintf("= attach %d %d\n", pid, tid);
609  }
610 
611  if (dbg->cur && dbg->cur->select && !dbg->cur->select(dbg, pid, tid)) {
612  return false;
613  }
614 
615  // Don't change the pid/tid if the plugin already modified it due to internal constraints
616  if (dbg->pid == prev_pid) {
617  dbg->pid = pid;
618  }
619  if (dbg->tid == prev_tid) {
620  dbg->tid = tid;
621  }
622 
623  rz_io_system(dbg->iob.io, sdb_fmt("pid %d", dbg->tid));
624 
625  // Synchronize with the current thread's data
626  if (dbg->corebind.core) {
627  RzCore *core = (RzCore *)dbg->corebind.core;
628 
629  rz_reg_arena_swap(core->dbg->reg, true);
631 
632  pc = rz_debug_reg_get(dbg, "PC");
633  core->offset = pc;
634  }
635 
636  return true;
637 }
638 
640  switch (type) {
641  case RZ_DEBUG_REASON_DEAD: return "dead";
642  case RZ_DEBUG_REASON_ABORT: return "abort";
643  case RZ_DEBUG_REASON_SEGFAULT: return "segfault";
644  case RZ_DEBUG_REASON_NONE: return "none";
645  case RZ_DEBUG_REASON_SIGNAL: return "signal";
646  case RZ_DEBUG_REASON_BREAKPOINT: return "breakpoint";
647  case RZ_DEBUG_REASON_TRACEPOINT: return "tracepoint";
648  case RZ_DEBUG_REASON_READERR: return "read-error";
649  case RZ_DEBUG_REASON_WRITERR: return "write-error";
650  case RZ_DEBUG_REASON_DIVBYZERO: return "div-by-zero";
651  case RZ_DEBUG_REASON_ILLEGAL: return "illegal";
652  case RZ_DEBUG_REASON_UNKNOWN: return "unknown";
653  case RZ_DEBUG_REASON_ERROR: return "error";
654  case RZ_DEBUG_REASON_NEW_PID: return "new-pid";
655  case RZ_DEBUG_REASON_NEW_TID: return "new-tid";
656  case RZ_DEBUG_REASON_NEW_LIB: return "new-lib";
657  case RZ_DEBUG_REASON_EXIT_PID: return "exit-pid";
658  case RZ_DEBUG_REASON_EXIT_TID: return "exit-tid";
659  case RZ_DEBUG_REASON_EXIT_LIB: return "exit-lib";
660  case RZ_DEBUG_REASON_TRAP: return "trap";
661  case RZ_DEBUG_REASON_SWI: return "software-interrupt";
662  case RZ_DEBUG_REASON_INT: return "interrupt";
663  case RZ_DEBUG_REASON_FPU: return "fpu";
664  case RZ_DEBUG_REASON_STEP: return "step";
665  case RZ_DEBUG_REASON_USERSUSP: return "suspended-by-user";
666  }
667  return "unhandled";
668 }
669 
671  // TODO: return reason to stop debugging
672  // - new process
673  // - trap instruction
674  // - illegal instruction
675  // - fpu exception
676  // return dbg->reason
677  return dbg->reason.type;
678 }
679 
680 /*
681  * wait for an event to happen on the selected pid/tid
682  *
683  * Returns RZ_DEBUG_REASON_*
684  */
687  if (!dbg) {
688  return reason;
689  }
690 
691  if (bp) {
692  *bp = NULL;
693  }
694  /* default to unknown */
696  if (rz_debug_is_dead(dbg)) {
697  return RZ_DEBUG_REASON_DEAD;
698  }
699 
700  /* if our debugger plugin has wait */
701  if (dbg->cur && dbg->cur->wait) {
702  reason = dbg->cur->wait(dbg, dbg->pid);
703  if (reason == RZ_DEBUG_REASON_DEAD) {
704  eprintf("\n==> Process finished\n\n");
706  .pid = dbg->pid
707  };
709  // XXX(jjd): TODO: handle fallback or something else
710  // rz_debug_select (dbg, -1, -1);
711  return RZ_DEBUG_REASON_DEAD;
712  }
713 
714 #if __linux__
715  // Letting other threads running will cause ptrace commands to fail
716  // when writing to the same process memory to set/unset breakpoints
717  // and is problematic in Linux.
718  if (dbg->continue_all_threads) {
720  }
721 #endif
722 
723  /* propagate errors from the plugin */
724  if (reason == RZ_DEBUG_REASON_ERROR) {
725  return RZ_DEBUG_REASON_ERROR;
726  }
727 
728  /* read general purpose registers */
729  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
730  return RZ_DEBUG_REASON_ERROR;
731  }
732 
733  bool libs_bp = (dbg->glob_libs || dbg->glob_unlibs) ? true : false;
734  /* if the underlying stop reason is a breakpoint, call the handlers */
735  if (reason == RZ_DEBUG_REASON_BREAKPOINT ||
736  reason == RZ_DEBUG_REASON_STEP ||
737  (libs_bp && ((reason == RZ_DEBUG_REASON_NEW_LIB) || (reason == RZ_DEBUG_REASON_EXIT_LIB)))) {
738  RzRegItem *pc_ri;
740  ut64 pc;
741 
742  /* get the program coounter */
743  pc_ri = rz_reg_get(dbg->reg, dbg->reg->name[RZ_REG_NAME_PC], -1);
744  if (!pc_ri) { /* couldn't find PC?! */
745  eprintf("Couldn't find PC!\n");
746  return RZ_DEBUG_REASON_ERROR;
747  }
748 
749  /* get the value */
750  pc = rz_reg_get_value(dbg->reg, pc_ri);
751 
752  if (!rz_debug_bp_hit(dbg, pc_ri, pc, &b)) {
753  return RZ_DEBUG_REASON_ERROR;
754  }
755 
756  if (bp) {
757  *bp = b;
758  }
759 
760  if (b && reason == RZ_DEBUG_REASON_STEP) {
762  }
763  /* if we hit a tracing breakpoint, we need to continue in
764  * whatever mode the user desired. */
765  if (dbg->corebind.core && b && b->cond) {
766  reason = RZ_DEBUG_REASON_COND;
767  }
768  if (b && b->trace) {
770  }
771  }
772 
773  dbg->reason.type = reason;
774  if (reason == RZ_DEBUG_REASON_SIGNAL && dbg->reason.signum != -1) {
775  /* handle signal on continuations here */
776  int what = rz_debug_signal_what(dbg, dbg->reason.signum);
777  const char *name = rz_signal_to_string(dbg->reason.signum);
778  if (name && strcmp("SIGTRAP", name)) {
779  rz_cons_printf("[+] signal %d aka %s received %d\n",
780  dbg->reason.signum, name, what);
781  }
782  }
783  }
784  return reason;
785 }
786 
788  ut8 buf[32];
789  ut64 pc, sp, r;
790  ut64 next[2];
792  int br, i, ret;
793  union {
794  ut64 r64;
795  ut32 r32[2];
796  } sp_top;
797  union {
798  ut64 r64;
799  ut32 r32[2];
800  } memval;
801 
804  }
805 
806  if (rz_debug_is_dead(dbg)) {
807  return false;
808  }
809 
810  const bool has_lr_reg = rz_reg_get_name(dbg->reg, RZ_REG_NAME_LR);
811  const bool arch_ret_is_pop = !strcmp(dbg->arch, "arm") && dbg->bits <= RZ_SYS_BITS_32;
812 
815 
816  if (!dbg->iob.read_at) {
817  return false;
818  }
819  if (!dbg->iob.read_at(dbg->iob.io, pc, buf, sizeof(buf))) {
820  return false;
821  }
822  if (rz_analysis_op(dbg->analysis, &op, pc, buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
823  return false;
824  }
825  if (op.type == RZ_ANALYSIS_OP_TYPE_ILL) {
826  return false;
827  }
828  switch (op.type) {
830  if (arch_ret_is_pop && op.stackop == RZ_ANALYSIS_STACK_INC) {
831  dbg->iob.read_at(dbg->iob.io, sp - op.stackptr - 4, (ut8 *)&sp_top, 4);
832  next[0] = sp_top.r32[0];
833  } else if (has_lr_reg) {
835  } else {
836  dbg->iob.read_at(dbg->iob.io, sp, (ut8 *)&sp_top, 8);
837  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? sp_top.r32[0] : sp_top.r64;
838  }
839  br = 1;
840  break;
843  next[0] = op.jump;
844  next[1] = op.fail;
845  br = 2;
846  break;
849  next[0] = op.jump;
850  br = 1;
851  break;
854  r = rz_debug_reg_get(dbg, op.reg);
855  next[0] = r;
856  br = 1;
857  break;
860  r = rz_debug_reg_get(dbg, op.reg);
861  if (!dbg->iob.read_at(dbg->iob.io, r, (ut8 *)&memval, 8)) {
862  next[0] = op.addr + op.size;
863  } else {
864  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
865  }
866  br = 1;
867  break;
871  if (op.ireg) {
872  r = rz_debug_reg_get(dbg, op.ireg);
873  } else {
874  r = 0;
875  }
876  if (!dbg->iob.read_at(dbg->iob.io, r * op.scale + op.disp, (ut8 *)&memval, 8)) {
877  next[0] = op.addr + op.size;
878  } else {
879  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
880  }
881  br = 1;
882  break;
883  default:
884  next[0] = op.addr + op.size;
885  br = 1;
886  break;
887  }
888 
890  for (i = 0; i < br; i++) {
891  if (align > 1) {
892  next[i] = next[i] - (next[i] % align);
893  }
894  RzBreakpointItem *bpi = rz_bp_add_sw(dbg->bp, next[i], 0, RZ_PERM_X);
895  if (bpi) {
896  bpi->swstep = true;
897  }
898  }
899 
900  ret = rz_debug_continue(dbg);
901 
902  for (i = 0; i < br; i++) {
903  rz_bp_del(dbg->bp, next[i]);
904  }
905 
906  return ret;
907 }
908 
910  RzDebugReasonType reason;
911 
913  if (rz_debug_is_dead(dbg)) {
914  return false;
915  }
916 
917  /* only handle recoils when not already in recoil mode. */
919  /* handle the stage-2 of breakpoints */
921  return false;
922  }
923 
924  /* recoil already stepped once, so we don't step again. */
927  return true;
928  }
929  }
930 
931  if (!dbg->cur->step(dbg)) {
932  return false;
933  }
934 
935 #if __linux__
936  // Turn off continue_all_threads to make sure linux_dbg_wait
937  // only waits for one target for a single-step or breakpoint trap
938  bool prev_continue = dbg->continue_all_threads;
939  dbg->continue_all_threads = false;
940 #endif
941  reason = rz_debug_wait(dbg, pb);
942 #if __linux__
943  dbg->continue_all_threads = prev_continue;
944 #endif
945 
946  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
947  return false;
948  }
949  // Unset breakpoints before leaving
950  if (reason != RZ_DEBUG_REASON_BREAKPOINT &&
951  reason != RZ_DEBUG_REASON_COND &&
952  reason != RZ_DEBUG_REASON_TRACEPOINT) {
953  rz_bp_restore(dbg->bp, false);
954  }
955  /* TODO: handle better */
956  if (reason == RZ_DEBUG_REASON_ERROR) {
957  return false;
958  }
959  return true;
960 }
961 
962 RZ_API int rz_debug_step(RzDebug *dbg, int steps) {
963  RzBreakpointItem *bp = NULL;
964  int ret, steps_taken = 0;
965 
966  /* who calls this without giving a positive number? */
967  if (steps < 1) {
968  steps = 1;
969  }
970 
971  if (!dbg || !dbg->cur) {
972  return steps_taken;
973  }
974 
975  if (rz_debug_is_dead(dbg)) {
976  return steps_taken;
977  }
978 
980 
981  if (dbg->session) {
982  if (dbg->session->cnum != dbg->session->maxcnum) {
983  steps_taken = rz_debug_step_cnum(dbg, steps);
984  }
985  }
986 
987  for (; steps_taken < steps; steps_taken++) {
989  dbg->session->cnum++;
990  dbg->session->maxcnum++;
991  dbg->session->bp = 0;
993  eprintf("trace_ins_before: failed\n");
994  }
995  }
996 
997  if (dbg->swstep) {
998  ret = rz_debug_step_soft(dbg);
999  } else {
1000  ret = rz_debug_step_hard(dbg, &bp);
1001  }
1002  if (!ret) {
1003  eprintf("Stepping failed!\n");
1004  return steps_taken;
1005  }
1006 
1008  if (!rz_debug_trace_ins_after(dbg)) {
1009  eprintf("trace_ins_after: failed\n");
1010  }
1012  dbg->session->bp = bp;
1013  }
1014 
1015  dbg->steps++;
1017  }
1018 
1019  return steps_taken;
1020 }
1021 
1022 static bool isStepOverable(ut64 opType) {
1023  switch (opType & RZ_ANALYSIS_OP_TYPE_MASK) {
1028  return true;
1029  }
1030  return false;
1031 }
1032 
1034  RzAnalysisOp op;
1035  ut64 buf_pc, pc, ins_size;
1036  ut8 buf[DBG_BUF_SIZE];
1037  int steps_taken = 0;
1038 
1039  if (rz_debug_is_dead(dbg)) {
1040  return steps_taken;
1041  }
1042 
1043  if (steps < 1) {
1044  steps = 1;
1045  }
1046 
1047  if (dbg->cur && dbg->cur->step_over) {
1048  for (; steps_taken < steps; steps_taken++) {
1050  dbg->session->cnum++;
1051  dbg->session->maxcnum++;
1053  }
1054  if (!dbg->cur->step_over(dbg)) {
1055  return steps_taken;
1056  }
1059  }
1060  }
1061  return steps_taken;
1062  }
1063 
1064  if (!dbg->analysis || !dbg->reg) {
1065  return steps_taken;
1066  }
1067 
1068  // Initial refill
1070  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1071 
1072  for (; steps_taken < steps; steps_taken++) {
1074  // Try to keep the buffer full
1075  if (pc - buf_pc > sizeof(buf)) {
1076  buf_pc = pc;
1077  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1078  }
1079  // Analyze the opcode
1080  if (rz_analysis_op(dbg->analysis, &op, pc, buf + (pc - buf_pc), sizeof(buf) - (pc - buf_pc), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
1081  eprintf("debug-step-over: Decode error at %" PFMT64x "\n", pc);
1082  return steps_taken;
1083  }
1084  if (op.fail == -1) {
1085  ins_size = pc + op.size;
1086  } else {
1087  // Use op.fail here instead of pc+op.size to enforce analysis backends to fill in this field
1088  ins_size = op.fail;
1089  }
1090  // Skip over all the subroutine calls
1091  if (isStepOverable(op.type)) {
1092  if (!rz_debug_continue_until(dbg, ins_size)) {
1093  eprintf("Could not step over call @ 0x%" PFMT64x "\n", pc);
1094  return steps_taken;
1095  }
1097  // eprintf ("REP: skip to next instruction...\n");
1098  if (!rz_debug_continue_until(dbg, ins_size)) {
1099  eprintf("step over failed over rep\n");
1100  return steps_taken;
1101  }
1102  } else {
1103  rz_debug_step(dbg, 1);
1104  }
1105  }
1106 
1107  return steps_taken;
1108 }
1109 
1111  if (cnum > dbg->session->maxcnum) {
1112  eprintf("Error: out of cnum range\n");
1113  return false;
1114  }
1115  dbg->session->cnum = cnum;
1117 
1118  return true;
1119 }
1120 
1122  if (steps > dbg->session->cnum) {
1123  steps = dbg->session->cnum;
1124  }
1125  if (!rz_debug_goto_cnum(dbg, dbg->session->cnum - steps)) {
1126  return -1;
1127  }
1128  return steps;
1129 }
1130 
1132  if (steps > dbg->session->maxcnum - dbg->session->cnum) {
1133  steps = dbg->session->maxcnum - dbg->session->cnum;
1134  }
1135 
1136  rz_debug_goto_cnum(dbg, dbg->session->cnum + steps);
1137 
1138  return steps;
1139 }
1140 
1143  int ret = 0;
1144  RzBreakpointItem *bp = NULL;
1145 
1146  if (!dbg) {
1147  return 0;
1148  }
1149 
1150  // If the debugger is not at the end of the changes
1151  // Go to the end or the next breakpoint in the changes
1152  if (dbg->session && dbg->session->cnum != dbg->session->maxcnum) {
1153  bool has_bp = false;
1155  RzVector *vreg = ht_up_find(dbg->session->registers, ripc->offset | (ripc->arena << 16), NULL);
1157  rz_vector_foreach_prev(vreg, reg) {
1158  if (reg->cnum <= dbg->session->cnum) {
1159  continue;
1160  }
1161  has_bp = rz_bp_get_in(dbg->bp, reg->data, RZ_PERM_X) != NULL;
1162  if (has_bp) {
1163  eprintf("hit breakpoint at: 0x%" PFMT64x " cnum: %d\n", reg->data, reg->cnum);
1164  rz_debug_goto_cnum(dbg, reg->cnum);
1165  return dbg->tid;
1166  }
1167  }
1168 
1170  return dbg->tid;
1171  }
1172 
1173 repeat:
1174  if (rz_debug_is_dead(dbg)) {
1175  return 0;
1176  }
1177  if (dbg->session && dbg->trace_continue) {
1178  while (!rz_cons_is_breaked()) {
1179  if (rz_debug_step(dbg, 1) != 1) {
1180  break;
1181  }
1183  break;
1184  }
1185  }
1186  reason = dbg->session->reasontype;
1187  bp = dbg->session->bp;
1188  } else if (dbg->cur && dbg->cur->cont) {
1189  /* handle the stage-2 of breakpoints */
1191  return 0;
1192  }
1193  /* tell the inferior to go! */
1194  ret = dbg->cur->cont(dbg, dbg->pid, dbg->tid, sig);
1195  // XXX(jjd): why? //dbg->reason.signum = 0;
1196  reason = rz_debug_wait(dbg, &bp);
1197  } else {
1198  return 0;
1199  }
1200 
1201  if (dbg->corebind.core) {
1202  RzCore *core = (RzCore *)dbg->corebind.core;
1203  RzNum *num = core->num;
1204  if (reason == RZ_DEBUG_REASON_COND) {
1205  if (bp && bp->cond && dbg->corebind.cmd) {
1206  dbg->corebind.cmd(dbg->corebind.core, bp->cond);
1207  }
1208  if (num->value) {
1209  goto repeat;
1210  }
1211  }
1212  }
1213  if (reason == RZ_DEBUG_REASON_BREAKPOINT &&
1214  ((bp && !bp->enabled) || (!bp && !rz_cons_is_breaked() && dbg->corebind.core && dbg->corebind.cfggeti(dbg->corebind.core, "dbg.bpsysign")))) {
1215  goto repeat;
1216  }
1217 
1218 #if __linux__
1219  if (reason == RZ_DEBUG_REASON_NEW_PID && dbg->follow_child) {
1220 #if DEBUGGER
1223  static bool (*linux_attach_new_process)(RzDebug * dbg, int pid) = NULL;
1224  if (!linux_attach_new_process) {
1225  linux_attach_new_process = rz_lib_dl_sym(NULL, "linux_attach_new_process");
1226  }
1229  }
1230 #endif
1231  goto repeat;
1232  }
1233 
1234  if (reason == RZ_DEBUG_REASON_NEW_TID) {
1235  ret = dbg->tid;
1236  if (!dbg->trace_clone) {
1237  goto repeat;
1238  }
1239  }
1240 
1241  if (reason == RZ_DEBUG_REASON_EXIT_TID) {
1242  goto repeat;
1243  }
1244 #endif
1245  if (reason != RZ_DEBUG_REASON_DEAD) {
1246  ret = dbg->tid;
1247  }
1248 #if __WINDOWS__
1249  if (reason == RZ_DEBUG_REASON_NEW_LIB ||
1250  reason == RZ_DEBUG_REASON_EXIT_LIB ||
1251  reason == RZ_DEBUG_REASON_NEW_TID ||
1252  reason == RZ_DEBUG_REASON_NONE ||
1253  reason == RZ_DEBUG_REASON_EXIT_TID) {
1254  goto repeat;
1255  }
1256 #endif
1257  if (reason == RZ_DEBUG_REASON_EXIT_PID) {
1258 #if __WINDOWS__
1259  dbg->pid = -1;
1260 #elif __linux__
1262  rz_bp_restore(dbg->bp, false); // (vdf) there has got to be a better way
1263 #endif
1264  }
1265 
1266  /* if continuing killed the inferior, we won't be able to get
1267  * the registers.. */
1268  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
1269  return 0;
1270  }
1271 
1272  /* if we hit a tracing breakpoint, we need to continue in
1273  * whatever mode the user desired. */
1274  if (reason == RZ_DEBUG_REASON_TRACEPOINT) {
1275  rz_debug_step(dbg, 1);
1276  goto repeat;
1277  }
1278 
1279  /* choose the thread that was returned from the continue function */
1280  // XXX(jjd): there must be a cleaner way to do this...
1281  if (ret != dbg->tid) {
1282  rz_debug_select(dbg, dbg->pid, ret);
1283  }
1284  sig = 0; // clear continuation after signal if needed
1285 
1286  /* handle general signals here based on the return from the wait
1287  * function */
1288  if (dbg->reason.signum != -1) {
1289  int what = rz_debug_signal_what(dbg, dbg->reason.signum);
1290  if (what & RZ_DBG_SIGNAL_CONT) {
1291  sig = dbg->reason.signum;
1292  eprintf("Continue into the signal %d handler\n", sig);
1293  goto repeat;
1294  } else if (what & RZ_DBG_SIGNAL_SKIP) {
1295  // skip signal. requires skipping one instruction
1296  ut8 buf[64];
1297  RzAnalysisOp op = { 0 };
1298  ut64 pc = rz_debug_reg_get(dbg, "PC");
1299  dbg->iob.read_at(dbg->iob.io, pc, buf, sizeof(buf));
1301  if (op.size > 0) {
1302  const char *signame = rz_signal_to_string(dbg->reason.signum);
1303  rz_debug_reg_set(dbg, "PC", pc + op.size);
1304  eprintf("Skip signal %d handler %s\n",
1305  dbg->reason.signum, signame);
1306  goto repeat;
1307  } else {
1308  ut64 pc = rz_debug_reg_get(dbg, "PC");
1309  eprintf("Stalled with an exception at 0x%08" PFMT64x "\n", pc);
1310  }
1311  }
1312  }
1313 #if __WINDOWS__
1315 #endif
1316 
1317  // Unset breakpoints before leaving
1318  if (reason != RZ_DEBUG_REASON_BREAKPOINT) {
1319  rz_bp_restore(dbg->bp, false);
1320  }
1321 
1322  // Add a checkpoint at stops
1323  if (dbg->session && !dbg->trace_continue) {
1324  dbg->session->cnum++;
1325  dbg->session->maxcnum++;
1327  }
1328 
1329  return ret;
1330 }
1331 
1333  return rz_debug_continue_kill(dbg, 0); // dbg->reason.signum);
1334 }
1335 
1338 }
1339 
1341  eprintf("TODO\n");
1342  return false;
1343 }
1344 
1346  int ret, n = 0;
1347  ut64 pc, buf_pc = 0;
1348  RzAnalysisOp op;
1349  ut8 buf[DBG_BUF_SIZE];
1350 
1351  if (rz_debug_is_dead(dbg)) {
1352  return false;
1353  }
1354 
1355  if (!dbg->analysis || !dbg->reg) {
1356  eprintf("Undefined pointer at dbg->analysis\n");
1357  return false;
1358  }
1359 
1360  rz_debug_step(dbg, 1);
1362 
1363  // Initial refill
1365  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1366 
1367  // step first, we don't want to check current optype
1368  for (;;) {
1369  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1370  break;
1371  }
1372 
1374  // Try to keep the buffer full
1375  if (pc - buf_pc > sizeof(buf)) {
1376  buf_pc = pc;
1377  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1378  }
1379  // Analyze the opcode
1380  if (rz_analysis_op(dbg->analysis, &op, pc, buf + (pc - buf_pc), sizeof(buf) - (pc - buf_pc), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
1381  eprintf("Decode error at %" PFMT64x "\n", pc);
1382  return false;
1383  }
1384  if (op.type == type) {
1385  break;
1386  }
1387  // Step over and repeat
1388  ret = over
1389  ? rz_debug_step_over(dbg, 1)
1390  : rz_debug_step(dbg, 1);
1391 
1392  if (!ret) {
1393  eprintf("rz_debug_step: failed\n");
1394  break;
1395  }
1396  n++;
1397  }
1398 
1399  return n;
1400 }
1401 
1403  if (rz_debug_is_dead(dbg)) {
1404  return false;
1405  }
1406  // Check if there was another breakpoint set at addr
1407  bool has_bp = rz_bp_get_in(dbg->bp, addr, RZ_PERM_X) != NULL;
1408  if (!has_bp) {
1409  rz_bp_add_sw(dbg->bp, addr, 0, RZ_PERM_X);
1410  }
1411 
1412  // Continue until the bp is reached
1413  dbg->reason.type = 0;
1414  for (;;) {
1415  if (rz_debug_is_dead(dbg) || dbg->reason.type) {
1416  break;
1417  }
1419  if (pc == addr) {
1420  break;
1421  }
1422  if (block && rz_bp_get_at(dbg->bp, pc)) {
1423  break;
1424  }
1426  }
1427  // Clean up if needed
1428  if (!has_bp) {
1429  rz_bp_del(dbg->bp, addr);
1430  }
1431  return true;
1432 }
1433 
1435  return rz_debug_continue_until_internal(dbg, addr, true);
1436 }
1437 
1439  return rz_debug_continue_until_internal(dbg, addr, false);
1440 }
1441 
1443  int cnum;
1444  bool has_bp = false;
1445 
1447  RzVector *vreg = ht_up_find(dbg->session->registers, ripc->offset | (ripc->arena << 16), NULL);
1448  if (!vreg) {
1449  eprintf("Error: cannot find PC change vector");
1450  return false;
1451  }
1453  rz_vector_foreach_prev(vreg, reg) {
1454  if (reg->cnum >= dbg->session->cnum) {
1455  continue;
1456  }
1457  has_bp = rz_bp_get_in(dbg->bp, reg->data, RZ_PERM_X) != NULL;
1458  if (has_bp) {
1459  cnum = reg->cnum;
1460  eprintf("hit breakpoint at: 0x%" PFMT64x " cnum: %d\n", reg->data, reg->cnum);
1461  break;
1462  }
1463  }
1464 
1465  if (has_bp) {
1466  rz_debug_goto_cnum(dbg, cnum);
1467  } else {
1468  if (dbg->session->maxcnum > 0) {
1469  rz_debug_goto_cnum(dbg, 0);
1470  }
1471  }
1472 
1473  return true;
1474 }
1475 
1476 static int show_syscall(RzDebug *dbg, const char *sysreg) {
1477  const char *sysname;
1478  char regname[32];
1479  int reg, i, args;
1480  RzSyscallItem *si;
1481  reg = (int)rz_debug_reg_get(dbg, sysreg);
1483  if (si) {
1484  sysname = si->name ? si->name : "unknown";
1485  args = si->args;
1486  } else {
1487  sysname = "unknown";
1488  args = 3;
1489  }
1490  eprintf("--> %s 0x%08" PFMT64x " syscall %d %s (", sysreg,
1491  rz_debug_reg_get(dbg, "PC"), reg, sysname);
1492  for (i = 0; i < args; i++) {
1493  ut64 val;
1494  snprintf(regname, sizeof(regname) - 1, "A%d", i);
1496  if (((st64)val < 0) && ((st64)val > -0xffff)) {
1497  eprintf("%" PFMT64d "%s", val, (i + 1 == args) ? "" : " ");
1498  } else {
1499  eprintf("0x%" PFMT64x "%s", val, (i + 1 == args) ? "" : " ");
1500  }
1501  }
1502  eprintf(")\n");
1504  return reg;
1505 }
1506 
1508  int i, reg, ret = false;
1509  if (!dbg || !dbg->cur || rz_debug_is_dead(dbg)) {
1510  return false;
1511  }
1512  if (!dbg->cur->contsc) {
1513  /* user-level syscall tracing */
1515  return show_syscall(dbg, "A0");
1516  }
1517 
1518  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1519  eprintf("--> cannot read registers\n");
1520  return -1;
1521  }
1522 
1524  eprintf("Cannot find 'sn' register for current arch-os.\n");
1525  return -1;
1526  }
1527  for (;;) {
1528  RzDebugReasonType reason;
1529 
1530  if (rz_cons_singleton()->context->breaked) {
1531  break;
1532  }
1533 #if __linux__
1534  // step is needed to avoid dupped contsc results
1535  /* XXX(jjd): actually one stop is before the syscall, the other is
1536  * after. this allows you to inspect the arguments before and the
1537  * return value after... */
1538  rz_debug_step(dbg, 1);
1539 #endif
1540  dbg->cur->contsc(dbg, dbg->pid, 0); // TODO handle return value
1541  // wait until continuation
1542  reason = rz_debug_wait(dbg, NULL);
1543  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
1544  break;
1545  }
1546 #if 0
1547  if (reason != RZ_DEBUG_REASON_STEP) {
1548  eprintf ("astep\n");
1549  break;
1550  }
1551 #endif
1552  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1553  eprintf("--> cannot sync regs, process is probably dead\n");
1554  return -1;
1555  }
1556  reg = show_syscall(dbg, "SN");
1557 
1558  if (dbg->corebind.core && dbg->corebind.syshit) {
1560  }
1561 
1562  if (n_sc == -1) {
1563  continue;
1564  }
1565  if (n_sc == 0) {
1566  break;
1567  }
1568  for (i = 0; i < n_sc; i++) {
1569  if (sc[i] == reg) {
1570  return reg;
1571  }
1572  }
1573  // TODO: must use rz_core_cmd(as)..import code from rcore
1574  }
1575  return ret;
1576 }
1577 
1579  return rz_debug_continue_syscalls(dbg, &sc, 1);
1580 }
1581 
1582 // TODO: remove from here? this is code injection!
1584  bool ret = true;
1585  if (dbg->cur->contsc) {
1586  ret = dbg->cur->contsc(dbg, dbg->pid, num);
1587  }
1588  eprintf("TODO: show syscall information\n");
1589  /* rz_testc task? ala inject? */
1590  return (int)ret;
1591 }
1592 
1595  return !rz_debug_is_dead(dbg) && dbg->cur && dbg->cur->kill;
1596 }
1597 
1598 RZ_API int rz_debug_kill(RzDebug *dbg, int pid, int tid, int sig) {
1599  if (rz_debug_is_dead(dbg)) {
1600  return false;
1601  }
1602  if (dbg->cur && dbg->cur->kill) {
1603  if (pid > 0) {
1604  return dbg->cur->kill(dbg, pid, tid, sig);
1605  }
1606  return -1;
1607  }
1608  eprintf("Backend does not implement kill()\n");
1609  return false;
1610 }
1611 
1613  if (dbg && dbg->cur && dbg->cur->frames) {
1614  return dbg->cur->frames(dbg, at);
1615  }
1616  return NULL;
1617 }
1618 
1619 /* TODO: Implement fork and clone */
1621  // if (dbg && dbg->cur && dbg->cur->frames)
1622  // return dbg->cur->frames (dbg);
1623  return 0;
1624 }
1625 
1627  // if (dbg && dbg->cur && dbg->cur->frames)
1628  // return dbg->cur->frames (dbg);
1629  return 0;
1630 }
1631 
1633  if (!dbg->cur) {
1634  return false;
1635  }
1636  // workaround for debug.io.. should be generic
1637  if (!strcmp(dbg->cur->name, "io")) {
1638  return false;
1639  }
1640  bool is_dead = (dbg->pid == -1 && strncmp(dbg->cur->name, "gdb", 3)) || (dbg->reason.type == RZ_DEBUG_REASON_DEAD);
1641  if (dbg->pid > 0 && dbg->cur && dbg->cur->kill) {
1642  is_dead = !dbg->cur->kill(dbg, dbg->pid, false, 0);
1643  }
1644 #if 0
1645  if (!is_dead && dbg->cur && dbg->cur->kill) {
1646  is_dead = !dbg->cur->kill (dbg, dbg->pid, false, 0);
1647  }
1648 #endif
1649  if (is_dead) {
1651  }
1652  return is_dead;
1653 }
1654 
1656  if (dbg && dbg->cur && dbg->cur->map_protect) {
1657  return dbg->cur->map_protect(dbg, addr, size, perms);
1658  }
1659  return false;
1660 }
1661 
1663  if (dbg && dbg->cur && dbg->cur->drx) {
1664  dbg->cur->drx(dbg, 0, 0, 0, 0, 0, DRX_API_LIST);
1665  }
1666 }
1667 
1668 RZ_API int rz_debug_drx_set(RzDebug *dbg, int idx, ut64 addr, int len, int rwx, int g) {
1669  if (dbg && dbg->cur && dbg->cur->drx) {
1670  return dbg->cur->drx(dbg, idx, addr, len, rwx, g, DRX_API_SET_BP);
1671  }
1672  return false;
1673 }
1674 
1676  if (dbg && dbg->cur && dbg->cur->drx) {
1677  return dbg->cur->drx(dbg, idx, 0, -1, 0, 0, DRX_API_REMOVE_BP);
1678  }
1679  return false;
1680 }
1681 
1683  if (!dbg || !dbg->iob.io || !dbg->iob.io->desc) {
1684  return 0LL;
1685  }
1686  if (!strcmp(dbg->iob.io->desc->plugin->name, "gdb")) { // this is very bad
1687  // Tell gdb that we want baddr, not full mem map
1688  dbg->iob.system(dbg->iob.io, "baddr");
1689  }
1690  int pid = rz_io_desc_get_pid(dbg->iob.io->desc);
1691  int tid = rz_io_desc_get_tid(dbg->iob.io->desc);
1692  if (pid < 0 || tid < 0) {
1693  return 0LL;
1694  }
1695  if (rz_debug_attach(dbg, pid) == -1) {
1696  return 0LL;
1697  }
1698 #if __WINDOWS__
1699  ut64 base;
1700  bool ret = rz_io_desc_get_base(dbg->iob.io->desc, &base);
1701  if (ret) {
1702  return base;
1703  }
1704 #endif
1705  RzListIter *iter;
1706  RzDebugMap *map;
1707  rz_debug_select(dbg, pid, tid);
1709  char *abspath = rz_sys_pid_to_path(pid);
1710 #if !__WINDOWS__
1711  if (!abspath) {
1712  abspath = rz_file_abspath(file);
1713  }
1714 #endif
1715  if (!abspath) {
1716  abspath = strdup(file);
1717  }
1718  if (abspath) {
1719  rz_list_foreach (dbg->maps, iter, map) {
1720  if (!strcmp(abspath, map->name)) {
1721  free(abspath);
1722  return map->addr;
1723  }
1724  }
1725  free(abspath);
1726  }
1727  // fallback resolution (osx/w32?)
1728  // we assume maps to be loaded in order, so lower addresses come first
1729  rz_list_foreach (dbg->maps, iter, map) {
1730  if (map->perm == 5) { // r-x
1731  return map->addr;
1732  }
1733  }
1734  return 0LL;
1735 }
1736 
1737 RZ_API void rz_debug_bp_rebase(RzDebug *dbg, ut64 old_base, ut64 new_base) {
1738  RzBreakpointItem *bp;
1739  RzListIter *iter;
1740  ut64 diff = new_base - old_base;
1741  // update bp->baddr
1742  dbg->bp->baddr = new_base;
1743 
1744  // update bp's address
1745  rz_list_foreach (dbg->bp->bps, iter, bp) {
1746  bp->addr += diff;
1747  bp->delta = bp->addr - dbg->bp->baddr;
1748  }
1749 }
size_t len
Definition: 6502dis.c:15
ut8 op
Definition: 6502dis.c:13
si
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
lzma_index ** i
Definition: index.h:629
RZ_API bool rz_reg_read_regs(RzReg *reg, ut8 *buf, const int len)
Definition: arena.c:58
RZ_API ut8 * rz_reg_get_bytes(RzReg *reg, int type, int *size)
Definition: arena.c:8
RZ_API void rz_reg_arena_swap(RzReg *reg, int copy)
Definition: arena.c:196
ut16 val
Definition: armass64_const.h:6
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_ending_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint b that fulfills b->addr + b-> size == addr After hitting a (usually software) brea...
Definition: bp.c:119
RZ_API RzBreakpointItem * rz_bp_get_in(RzBreakpoint *bp, ut64 addr, int perm)
Definition: bp.c:139
RZ_API RzBreakpoint * rz_bp_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *ctx)
Definition: bp.c:26
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint at exactly addr.
Definition: bp.c:102
RZ_API RzBreakpoint * rz_bp_free(RzBreakpoint *bp)
Definition: bp.c:48
RZ_API bool rz_bp_del(RzBreakpoint *bp, ut64 addr)
Definition: bp.c:315
RZ_API RzBreakpointItem * rz_bp_add_hw(RzBreakpoint *bp, ut64 addr, int size, int perm)
Definition: bp.c:299
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_add_sw(RZ_NONNULL RzBreakpoint *bp, ut64 addr, int size, int perm)
Add a software breakpoint size preferred size of the breakpoint, or 0 to determine automatically.
Definition: bp.c:280
RZ_API int rz_bp_size_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Predict the software breakpoint size to use when placing a breakpoint at addr.
Definition: bp.c:399
RZ_API int rz_bp_restore(RzBreakpoint *bp, bool set)
Definition: bp_io.c:28
RZ_API bool rz_bp_restore_except(RzBreakpoint *bp, bool set, ut64 addr)
Definition: bp_io.c:37
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_watch_add(RZ_NONNULL RzBreakpoint *bp, ut64 addr, int size, int hw, int perm)
Definition: bp_watch.c:15
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
cs_arch arch
Definition: cstool.c:13
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
uint32_t ut32
RzDebug * dbg
Definition: desil.c:30
RZ_API RzList * rz_debug_map_list_new(void)
Definition: dmap.c:83
RZ_API bool rz_debug_map_sync(RzDebug *dbg)
Definition: dmap.c:33
RZ_API RzList * rz_debug_modules_list(RzDebug *dbg)
Definition: dmap.c:29
RZ_API ut64 rz_debug_num_callback(RzNum *userptr, const char *str, int *ok)
Definition: dreg.c:104
RZ_API ut64 rz_debug_reg_get(RzDebug *dbg, const char *name)
Definition: dreg.c:99
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write)
Definition: dreg.c:9
RZ_API int rz_debug_reg_set(struct rz_debug_t *dbg, const char *name, ut64 num)
Definition: dreg.c:89
RZ_API void rz_debug_session_free(RzDebugSession *session)
Definition: dsession.c:11
RZ_API bool rz_debug_add_checkpoint(RzDebug *dbg)
Definition: dsession.c:58
RZ_API void rz_debug_session_restore_reg_mem(RzDebug *dbg, ut32 cnum)
Definition: dsession.c:173
RZ_API void rz_debug_signal_init(RzDebug *dbg)
Definition: dsignal.c:54
RZ_API int rz_debug_signal_what(RzDebug *dbg, int num)
Definition: dsignal.c:151
RZ_API void rz_egg_free(RzEgg *egg)
Definition: egg.c:111
RZ_API RzEgg * rz_egg_new(void)
Definition: egg.c:44
RZ_API bool rz_egg_setup(RzEgg *egg, const char *arch, int bits, int endian, const char *os)
Definition: egg.c:139
static char sc[]
Definition: egg_cb.c:6
struct @667 g
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void rz_hash_free(RzHash *rh)
Definition: hash.c:597
RZ_API RzHash * rz_hash_new(void)
Definition: hash.c:585
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
RZ_API bool rz_debug_can_kill(RzDebug *dbg)
check whether rz_debug_kill() will not definitely fail (for example because kill is unimplemented by ...
Definition: debug.c:1594
RZ_API int rz_debug_kill(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug.c:1598
static int rz_debug_recoil(RzDebug *dbg, RzDebugRecoilMode rc_mode)
Definition: debug.c:223
RZ_API int rz_debug_syscall(RzDebug *dbg, int num)
Definition: debug.c:1583
static int rz_debug_continue_until_internal(RzDebug *dbg, ut64 addr, bool block)
Definition: debug.c:1402
RZ_API bool rz_debug_goto_cnum(RzDebug *dbg, ut32 cnum)
Definition: debug.c:1110
void free_tracenodes_kv(HtUPKv *kv)
Definition: debug.c:355
RZ_API int rz_debug_drx_set(RzDebug *dbg, int idx, ut64 addr, int len, int rwx, int g)
Definition: debug.c:1668
RZ_API int rz_debug_start(RzDebug *dbg, const char *cmd)
Definition: debug.c:577
RZ_LIB_VERSION(rz_debug)
RZ_API int rz_debug_continue_syscall(RzDebug *dbg, int sc)
Definition: debug.c:1578
RZ_API RZ_OWN RzDebug * rz_debug_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *bp_ctx)
Definition: debug.c:359
static bool isStepOverable(ut64 opType)
Definition: debug.c:1022
static int show_syscall(RzDebug *dbg, const char *sysreg)
Definition: debug.c:1476
RZ_API void rz_debug_bp_rebase(RzDebug *dbg, ut64 old_base, ut64 new_base)
Definition: debug.c:1737
RZ_API int rz_debug_step_back(RzDebug *dbg, int steps)
Definition: debug.c:1121
RZ_API int rz_debug_step_over(RzDebug *dbg, int steps)
Definition: debug.c:1033
RZ_API int rz_debug_step(RzDebug *dbg, int steps)
Definition: debug.c:962
RZ_API int rz_debug_map_protect(RzDebug *dbg, ut64 addr, int size, int perms)
Definition: debug.c:1655
RZ_API RZ_BORROW RzBreakpointItem * rz_debug_bp_add(RZ_NONNULL RzDebug *dbg, ut64 addr, int hw, bool watch, int rw, RZ_NULLABLE const char *module, st64 m_delta)
Definition: debug.c:270
RZ_API int rz_debug_continue_until_optype(RzDebug *dbg, int type, int over)
Definition: debug.c:1345
RZ_API bool rz_debug_continue_back(RzDebug *dbg)
Definition: debug.c:1442
RZ_API int rz_debug_continue_until(RzDebug *dbg, ut64 addr)
Definition: debug.c:1434
RZ_API RzDebug * rz_debug_free(RzDebug *dbg)
Definition: debug.c:416
RZ_API int rz_debug_drx_unset(RzDebug *dbg, int idx)
Definition: debug.c:1675
RZ_API int rz_debug_continue_until_nonblock(RzDebug *dbg, ut64 addr)
Definition: debug.c:1438
RZ_API int rz_debug_detach(RzDebug *dbg, int pid)
Definition: debug.c:583
RZ_API const char * rz_debug_reason_to_string(int type)
Definition: debug.c:639
RZ_API void rz_debug_bp_update(RzDebug *dbg)
Definition: debug.c:39
static const char * rz_debug_str_callback(RzNum *userptr, ut64 off, int *ok)
Definition: debug.c:349
RZ_API int rz_debug_continue(RzDebug *dbg)
Definition: debug.c:1332
RZ_API int rz_debug_stop(RzDebug *dbg)
Definition: debug.c:458
RZ_API RzDebugReasonType rz_debug_wait(RzDebug *dbg, RzBreakpointItem **bp)
Definition: debug.c:685
RZ_API int rz_debug_continue_syscalls(RzDebug *dbg, int *sc, int n_sc)
Definition: debug.c:1507
#define DBG_BUF_SIZE
Definition: debug.c:16
RZ_API int rz_debug_child_clone(RzDebug *dbg)
Definition: debug.c:1626
RZ_API int rz_debug_step_hard(RzDebug *dbg, RzBreakpointItem **pb)
Definition: debug.c:909
RZ_API int rz_debug_step_cnum(RzDebug *dbg, int steps)
Definition: debug.c:1131
RZ_API int rz_debug_child_fork(RzDebug *dbg)
Definition: debug.c:1620
RZ_API int rz_debug_attach(RzDebug *dbg, int pid)
Definition: debug.c:445
RZ_API int rz_debug_step_soft(RzDebug *dbg)
Definition: debug.c:787
RZ_API RzDebugInfo * rz_debug_info(RzDebug *dbg, const char *arg)
Definition: debug.c:18
RZ_API void rz_debug_tracenodes_reset(RzDebug *dbg)
Definition: debug.c:411
RZ_API int rz_debug_continue_until_nontraced(RzDebug *dbg)
Definition: debug.c:1340
RZ_API void rz_debug_drx_list(RzDebug *dbg)
Definition: debug.c:1662
RZ_API int rz_debug_continue_pass_exception(RzDebug *dbg)
Definition: debug.c:1336
RZ_API ut64 rz_debug_get_baddr(RzDebug *dbg, const char *file)
Definition: debug.c:1682
RZ_API int rz_debug_startv(struct rz_debug_t *dbg, int argc, char **argv)
Definition: debug.c:572
RZ_API ut64 rz_debug_execute(RzDebug *dbg, const ut8 *buf, int len, int restore)
Definition: debug.c:510
RZ_API bool rz_debug_is_dead(RzDebug *dbg)
Definition: debug.c:1632
RZ_API int rz_debug_continue_kill(RzDebug *dbg, int sig)
Definition: debug.c:1141
static int rz_debug_bps_enable(RzDebug *dbg)
Definition: debug.c:200
RZ_API bool rz_debug_set_arch(RzDebug *dbg, const char *arch, int bits)
Definition: debug.c:465
RZ_API bool rz_debug_select(RzDebug *dbg, int pid, int tid)
Definition: debug.c:595
RZ_API RzList * rz_debug_frames(RzDebug *dbg, ut64 at)
Definition: debug.c:1612
RZ_API RzDebugReasonType rz_debug_stop_reason(RzDebug *dbg)
Definition: debug.c:670
static int rz_debug_drx_at(RzDebug *dbg, ut64 addr)
Definition: debug.c:50
RZ_API void rz_debug_info_free(RzDebugInfo *rdi)
Definition: debug.c:28
static int rz_debug_bp_hit(RzDebug *dbg, RzRegItem *pc_ri, ut64 pc, RzBreakpointItem **pb)
Definition: debug.c:66
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
void * malloc(size_t size)
Definition: malloc.c:123
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 unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
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 unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
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")
bool linux_attach_new_process(RzDebug *dbg, int pid)
Definition: linux_debug.c:451
@ ok
Definition: lz4.c:1706
int args
Definition: mipsasm.c:18
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
int idx
Definition: setup.py:197
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
int off
Definition: pal.c:13
RZ_API void rz_debug_plugin_init(RzDebug *dbg)
Definition: plugin.c:9
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
RZ_API RzRegItem * rz_reg_get_by_role(RzReg *reg, RzRegisterId role)
Definition: reg.c:154
RZ_API void rz_reg_free(RzReg *reg)
Definition: reg.c:279
RZ_API RzReg * rz_reg_new(void)
Definition: reg.c:286
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_OP_PREFIX_REP
Definition: rz_analysis.h:348
@ RZ_ANALYSIS_OP_PREFIX_LOCK
Definition: rz_analysis.h:350
@ RZ_ANALYSIS_OP_PREFIX_REPNE
Definition: rz_analysis.h:349
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_NEW_TID
Definition: rz_debug.h:106
@ RZ_DEBUG_REASON_DEAD
Definition: rz_debug.h:90
@ RZ_DEBUG_REASON_STEP
Definition: rz_debug.h:98
@ RZ_DEBUG_REASON_WRITERR
Definition: rz_debug.h:100
@ RZ_DEBUG_REASON_READERR
Definition: rz_debug.h:97
@ RZ_DEBUG_REASON_ILLEGAL
Definition: rz_debug.h:102
@ RZ_DEBUG_REASON_TRACEPOINT
Definition: rz_debug.h:95
@ RZ_DEBUG_REASON_UNKNOWN
Definition: rz_debug.h:103
@ RZ_DEBUG_REASON_BREAKPOINT
Definition: rz_debug.h:94
@ RZ_DEBUG_REASON_USERSUSP
Definition: rz_debug.h:115
@ RZ_DEBUG_REASON_TRAP
Definition: rz_debug.h:111
@ RZ_DEBUG_REASON_ABORT
Definition: rz_debug.h:99
@ RZ_DEBUG_REASON_ERROR
Definition: rz_debug.h:104
@ RZ_DEBUG_REASON_NEW_LIB
Definition: rz_debug.h:107
@ RZ_DEBUG_REASON_EXIT_LIB
Definition: rz_debug.h:110
@ RZ_DEBUG_REASON_FPU
Definition: rz_debug.h:114
@ RZ_DEBUG_REASON_SEGFAULT
Definition: rz_debug.h:93
@ RZ_DEBUG_REASON_NONE
Definition: rz_debug.h:91
@ RZ_DEBUG_REASON_NEW_PID
Definition: rz_debug.h:105
@ RZ_DEBUG_REASON_EXIT_PID
Definition: rz_debug.h:108
@ RZ_DEBUG_REASON_EXIT_TID
Definition: rz_debug.h:109
@ RZ_DEBUG_REASON_SWI
Definition: rz_debug.h:112
@ RZ_DEBUG_REASON_DIVBYZERO
Definition: rz_debug.h:101
@ RZ_DEBUG_REASON_INT
Definition: rz_debug.h:113
@ RZ_DEBUG_REASON_SIGNAL
Definition: rz_debug.h:92
@ RZ_DEBUG_REASON_COND
Definition: rz_debug.h:96
RzDebugRecoilMode
Definition: rz_debug.h:80
@ RZ_DBG_RECOIL_STEP
Definition: rz_debug.h:82
@ RZ_DBG_RECOIL_CONTINUE
Definition: rz_debug.h:83
@ RZ_DBG_RECOIL_NONE
Definition: rz_debug.h:81
@ RZ_DBG_SIGNAL_CONT
Definition: rz_debug.h:71
@ RZ_DBG_SIGNAL_SKIP
Definition: rz_debug.h:72
@ DRX_API_SET_BP
Definition: rz_drx.h:7
@ DRX_API_GET_BP
Definition: rz_drx.h:6
@ DRX_API_REMOVE_BP
Definition: rz_drx.h:8
@ DRX_API_LIST
Definition: rz_drx.h:5
RZ_API void rz_event_send(RzEvent *ev, int type, void *data)
Definition: event.c:115
@ RZ_EVENT_DEBUG_PROCESS_FINISHED
Definition: rz_event.h:41
RZ_API char * rz_file_abspath(const char *file)
Definition: file.c:267
RZ_API char * rz_io_system(RzIO *io, const char *cmd)
Definition: io.c:411
RZ_API int rz_io_desc_get_tid(RzIODesc *desc)
Definition: io_desc.c:327
RZ_API int rz_io_desc_get_pid(RzIODesc *desc)
Definition: io_desc.c:310
RZ_API bool rz_io_desc_get_base(RzIODesc *desc, ut64 *base)
Definition: io_desc.c:344
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
Definition: lib.c:90
RZ_API RzNum * rz_num_new(RzNumCallback cb, RzNumCallback2 cb2, void *ptr)
Definition: unum.c:75
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API void rz_num_free(RzNum *num)
Definition: unum.c:87
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_SN
Definition: rz_reg.h:70
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
@ RZ_REG_NAME_LR
Definition: rz_reg.h:47
@ RZ_REG_NAME_A0
Definition: rz_reg.h:49
RZ_API const char * rz_signal_to_string(int code)
Definition: signal.c:63
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_sys_pid_to_path(int pid)
Definition: sys.c:920
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
@ RZ_SYS_BITS_16
Definition: rz_sys.h:19
RZ_API void rz_tree_free(RTree *t)
Definition: tree.c:76
RZ_API RTree * rz_tree_new(void)
Definition: tree.c:72
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_SYS_BITS
Definition: rz_types.h:520
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_SYS_ENDIAN
Definition: rz_types.h:521
#define RZ_SYS_ARCH
Definition: rz_types.h:519
#define RZ_SYS_OS
Definition: rz_types.h:587
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define RZ_BORROW
Definition: rz_types.h:63
#define st64
Definition: rz_types_base.h:10
#define rz_vector_foreach_prev(vec, it)
Definition: rz_vector.h:173
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
static int
Definition: sfsocketcall.h:114
#define b(i)
Definition: sha256.c:42
#define br(opcode, mask, lose, flags)
Definition: gzappend.c:170
Definition: sftypes.h:77
Definition: z80asm.h:102
RzSyscall * syscall
Definition: rz_analysis.h:570
Outer context of mappings/etc. in which the RzBreakpoint instance will operate in....
Definition: rz_bp.h:71
char * expr
Definition: rz_bp.h:61
st64 module_delta
Definition: rz_bp.h:44
char * module_name
Definition: rz_bp.h:43
char * name
Definition: rz_bp.h:42
bool swstep
Definition: rz_bp.h:48
ut64 addr
Definition: rz_bp.h:45
int enabled
Definition: rz_bp.h:53
char * cond
Definition: rz_bp.h:60
ut64 delta
Definition: rz_bp.h:46
RzIOBind iob
Definition: rz_bp.h:84
RzList * bps
Definition: rz_bp.h:93
ut64 baddr
Definition: rz_bp.h:96
RzCoreCmd cmd
Definition: rz_bind.h:32
RzCoreNumGet numGet
Definition: rz_bind.h:47
void * core
Definition: rz_bind.h:31
RzCoreDebugSyscallHit syshit
Definition: rz_bind.h:38
RzCoreDebugBpHit bphit
Definition: rz_bind.h:37
RzCoreConfigGetI cfggeti
Definition: rz_bind.h:43
ut64 offset
Definition: rz_core.h:301
RzDebug * dbg
Definition: rz_core.h:329
RzNum * num
Definition: rz_core.h:316
int(* detach)(RzDebug *dbg, int pid)
Definition: rz_debug.h:373
bool(* kill)(RzDebug *dbg, int pid, int tid, int sig)
Definition: rz_debug.h:386
int(* attach)(RzDebug *dbg, int pid)
Definition: rz_debug.h:372
RzDebugInfo *(* info)(RzDebug *dbg, const char *arg)
Definition: rz_debug.h:370
int(* step_over)(RzDebug *dbg)
Definition: rz_debug.h:382
RzList *(* frames)(RzDebug *dbg, ut64 at)
Definition: rz_debug.h:389
int(* drx)(RzDebug *dbg, int n, ut64 addr, int size, int rwx, int g, int api_type)
Definition: rz_debug.h:402
int(* select)(RzDebug *dbg, int pid, int tid)
Definition: rz_debug.h:374
int(* contsc)(RzDebug *dbg, int pid, int sc)
Definition: rz_debug.h:388
RzDebugReasonType(* wait)(RzDebug *dbg, int pid)
Definition: rz_debug.h:384
int(* map_protect)(RzDebug *dbg, ut64 addr, int size, int perms)
Definition: rz_debug.h:401
const char * name
Definition: rz_debug.h:359
int(* cont)(RzDebug *dbg, int pid, int tid, int sig)
Definition: rz_debug.h:383
int(* step)(RzDebug *dbg)
Definition: rz_debug.h:381
int(* stop)(RzDebug *dbg)
Definition: rz_debug.h:380
RzBreakpointItem * bp
Definition: rz_debug.h:197
RzCoreBind corebind
Definition: rz_debug.h:314
RzDebugRecoilMode recoil_mode
Definition: rz_debug.h:277
bool verbose
Definition: rz_debug.h:319
PrintfCallback cb_printf
Definition: rz_debug.h:292
int stop_all_threads
Definition: rz_debug.h:262
bool pc_at_bp_set
Definition: rz_debug.h:300
bool main_arena_resolved
Definition: rz_debug.h:320
RzList * maps_user
Definition: rz_debug.h:307
RzList * threads
Definition: rz_debug.h:251
RzDebugSession * session
Definition: rz_debug.h:311
RzHash * hash
Definition: rz_debug.h:303
char * snap_path
Definition: rz_debug.h:289
int forked_pid
Definition: rz_debug.h:249
int trace_execs
Definition: rz_debug.h:264
bool continue_all_threads
Definition: rz_debug.h:272
RzList * maps
Definition: rz_debug.h:306
RzEvent * ev
Definition: rz_debug.h:302
int trace_clone
Definition: rz_debug.h:266
int follow_child
Definition: rz_debug.h:267
int swstep
Definition: rz_debug.h:261
RzDebugReason reason
Definition: rz_debug.h:276
char * glob_unlibs
Definition: rz_debug.h:270
bool pc_at_bp
Definition: rz_debug.h:299
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295
RzEgg * egg
Definition: rz_debug.h:318
RzDebugTrace * trace
Definition: rz_debug.h:281
int steps
Definition: rz_debug.h:275
RzAnalysis * analysis
Definition: rz_debug.h:305
RTree * tree
Definition: rz_debug.h:283
RzAnalysisOp * cur_op
Definition: rz_debug.h:310
RzList * q_regs
Definition: rz_debug.h:287
char * glob_libs
Definition: rz_debug.h:269
char * arch
Definition: rz_debug.h:242
int n_threads
Definition: rz_debug.h:250
Sdb * sgnls
Definition: rz_debug.h:313
HtUP * tracenodes
Definition: rz_debug.h:282
RzReg * reg
Definition: rz_debug.h:286
RzList * call_frames
Definition: rz_debug.h:284
RzList * plugins
Definition: rz_debug.h:297
char * btalgo
Definition: rz_debug.h:258
int bits
Definition: rz_debug.h:243
bool nt_x86_xstate_supported
Track whether X86_FEATURE_XSAVE feature is supported on current kernel.
Definition: rz_debug.h:323
int trace_aftersyscall
Definition: rz_debug.h:265
bool trace_continue
Definition: rz_debug.h:309
void * plugin_data
Definition: rz_debug.h:296
RzIOBind iob
Definition: rz_debug.h:293
int hitinfo
XXX: MUST SET ///.
Definition: rz_debug.h:244
int glibc_version
Definition: rz_debug.h:321
int trace_forks
Definition: rz_debug.h:263
int main_pid
Definition: rz_debug.h:246
RzNum * num
Definition: rz_debug.h:317
RzBreakpoint * bp
Definition: rz_debug.h:288
RzIOReadAt read_at
Definition: rz_io.h:240
RzIOSystem system
Definition: rz_io.h:242
RzIOWriteAt write_at
Definition: rz_io.h:241
RzIO * io
Definition: rz_io.h:232
int init
Definition: rz_io.h:231
struct rz_io_plugin_t * plugin
Definition: rz_io.h:103
const char * name
Definition: rz_io.h:115
struct rz_io_desc_t * desc
Definition: rz_io.h:60
int arena
In which arena is this reg living. Usually equals type.
Definition: rz_reg.h:127
int offset
Offset into register profile in bits.
Definition: rz_reg.h:121
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149
bool valid
Definition: core.c:77
RZ_API void rz_syscall_item_free(RzSyscallItem *si)
Definition: syscall.c:325
RZ_API RzSyscallItem * rz_syscall_get(RzSyscall *s, int num, int swi)
Definition: syscall.c:345
#define bool
Definition: sysdefs.h:146
RZ_API void rz_debug_trace_free(RzDebugTrace *trace)
Definition: trace.c:29
RZ_API RzDebugTrace * rz_debug_trace_new(void)
Definition: trace.c:7
RZ_API bool rz_debug_trace_ins_after(RzDebug *dbg)
Definition: trace.c:110
RZ_API int rz_debug_trace_pc(RzDebug *dbg, ut64 pc)
Definition: trace.c:160
RZ_API bool rz_debug_trace_ins_before(RzDebug *dbg)
Definition: trace.c:46
Definition: dis.c:32
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static char * regname(int reg)
Definition: dis.c:71
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58