Rizin
unix-like reverse engineering framework and cli tools
bp_traptrace.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2010 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 // TODO: use rz_range here??
5 #include <rz_bp.h>
6 #include <rz_list.h>
7 
8 RZ_API void rz_bp_traptrace_free(void *ptr) {
9  RzBreakpointTrace *trace = ptr;
10  free(trace->buffer);
11  free(trace->traps);
12  free(trace->bits);
13  free(trace);
14 }
15 
17  RzList *list = rz_list_new();
18  if (!list) {
19  return NULL;
20  }
21  list->free = &rz_bp_traptrace_free;
22  return list;
23 }
24 
27  RzBreakpointTrace *trace;
28  rz_list_foreach (bp->traces, iter, trace) {
29  ut8 *buf = (enable) ? trace->traps : trace->buffer;
30  bp->iob.write_at(bp->iob.io, trace->addr, buf, trace->length);
31  }
32 }
33 
36  RzBreakpointTrace *trace;
37  rz_list_foreach (bp->traces, iter, trace) {
38  if (hard) {
39  rz_bp_traptrace_free(trace);
40  // XXX: This segfaults
41  // rz_list_delete (bp->traces, rz_list_iter_cur (iter));
42  } else {
43  memset(trace->bits, 0x00, trace->bitlen);
44  }
45  }
46  if (hard) {
47  // XXX: traces not freed correctly (memleak)
48  bp->traces = rz_list_new();
50  }
51 }
52 
53 // FIX: efficiency
55  int i, delta;
57  RzBreakpointTrace *trace;
58  rz_list_foreach (bp->traces, iter, trace) {
59  if (addr >= trace->addr && addr <= trace->addr_end) {
60  delta = (int)(addr - trace->addr);
61  for (i = delta; i < trace->length; i++) {
62  if (RZ_BIT_CHK(trace->bits, i)) {
63  return addr + i;
64  }
65  }
66  }
67  }
68  return 0LL;
69 }
70 
72  RzBreakpointTrace *trace;
73  ut8 *buf, *trap, *bits;
74  ut64 len;
75  int bitlen;
76  /* cannot map addr 0 */
77  if (from == 0LL) {
78  return false;
79  }
80  if (from > to) {
81  return false;
82  }
83  len = to - from;
84  if (len >= ST32_MAX) {
85  return false;
86  }
87  buf = (ut8 *)malloc((int)len);
88  if (!buf) {
89  return false;
90  }
91  trap = (ut8 *)malloc((int)len + 4);
92  if (!trap) {
93  free(buf);
94  return false;
95  }
96  bitlen = (len >> 4) + 1;
97  bits = malloc(bitlen);
98  if (!bits) {
99  free(buf);
100  free(trap);
101  return false;
102  }
103  // TODO: check return value
104  bp->iob.read_at(bp->iob.io, from, buf, len);
105  memset(bits, 0x00, bitlen);
106  rz_bp_get_bytes(bp, from, trap, len);
107 
108  trace = RZ_NEW(RzBreakpointTrace);
109  if (!trace) {
110  free(buf);
111  free(trap);
112  free(bits);
113  return false;
114  }
115  trace->addr = from;
116  trace->addr_end = to;
117  trace->bits = bits;
118  trace->traps = trap;
119  trace->buffer = buf;
120  trace->length = len;
121  if (!rz_list_append(bp->traces, trace)) {
122  free(buf);
123  free(trap);
124  free(trace);
125  return false;
126  }
127  // read a memory, overwrite it as breakpointing area
128  // every time it is hitted, instruction is restored
129  return true;
130 }
131 
133  int ret = false;
134  RzListIter *iter, *iter_tmp;
135  RzBreakpointTrace *trace;
136  rz_list_foreach_safe (bp->traces, iter, iter_tmp, trace) {
137  if (from >= trace->addr && from <= trace->addr_end) {
138  bp->iob.write_at(bp->iob.io, trace->addr,
139  trace->buffer, trace->length);
140  rz_bp_traptrace_free(trace);
141  rz_list_delete(bp->traces, iter);
142  ret = true;
143  }
144  }
145  return ret;
146 }
147 
149  int i;
150  RzListIter *iter;
151  RzBreakpointTrace *trace;
152  rz_list_foreach (bp->traces, iter, trace) {
153  for (i = 0; i < trace->bitlen; i++) {
154  if (RZ_BIT_CHK(trace->bits, i)) {
155  eprintf(" - 0x%08" PFMT64x "\n", trace->addr + (i << 4));
156  }
157  }
158  }
159 }
160 
162  int delta;
163  RzListIter *iter;
164  RzBreakpointTrace *trace;
165  rz_list_foreach (bp->traces, iter, trace) {
166  // TODO: do we really need len?
167  if (from >= trace->addr && from + len <= trace->addr_end) {
168  delta = (int)(from - trace->addr);
169  if (RZ_BIT_CHK(trace->bits, delta)) {
170  if (trace->traps[delta] == 0x00) {
171  return false; // already traced..debugger should stop
172  }
173  }
174  RZ_BIT_SET(trace->bits, delta);
175  return true;
176  }
177  }
178  return false;
179 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API int rz_bp_get_bytes(RZ_NONNULL RzBreakpoint *bp, ut64 addr, RZ_NONNULL ut8 *buf, int len)
Definition: bp.c:61
RZ_API int rz_bp_traptrace_at(RzBreakpoint *bp, ut64 from, int len)
Definition: bp_traptrace.c:161
RZ_API void rz_bp_traptrace_list(RzBreakpoint *bp)
Definition: bp_traptrace.c:148
RZ_API void rz_bp_traptrace_enable(RzBreakpoint *bp, int enable)
Definition: bp_traptrace.c:25
RZ_API ut64 rz_bp_traptrace_next(RzBreakpoint *bp, ut64 addr)
Definition: bp_traptrace.c:54
RZ_API int rz_bp_traptrace_add(RzBreakpoint *bp, ut64 from, ut64 to)
Definition: bp_traptrace.c:71
RZ_API void rz_bp_traptrace_free(void *ptr)
Definition: bp_traptrace.c:8
RZ_API void rz_bp_traptrace_reset(RzBreakpoint *bp, int hard)
Definition: bp_traptrace.c:34
RZ_API RzList * rz_bp_traptrace_new(void)
Definition: bp_traptrace.c:16
RZ_API int rz_bp_traptrace_free_at(RzBreakpoint *bp, ut64 from)
Definition: bp_traptrace.c:132
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
void * malloc(size_t size)
Definition: malloc.c:123
#define eprintf(x, y...)
Definition: rlcc.c:7
#define RZ_BIT_SET(x, y)
Definition: rz_types.h:311
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_BIT_CHK(x, y)
Definition: rz_types.h:316
#define PFMT64x
Definition: rz_types.h:393
#define ST32_MAX
Definition: rz_types_base.h:97
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
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 int
Definition: sfsocketcall.h:114
Definition: rz_bp.h:78
RzList * traces
Definition: rz_bp.h:86
RzIOBind iob
Definition: rz_bp.h:84
ut8 * bits
Definition: rz_bp.h:104
int bitlen
Definition: rz_bp.h:106
ut8 * traps
Definition: rz_bp.h:102
int length
Definition: rz_bp.h:105
ut64 addr_end
Definition: rz_bp.h:101
ut64 addr
Definition: rz_bp.h:100
ut8 * buffer
Definition: rz_bp.h:103
RzIOReadAt read_at
Definition: rz_io.h:240
RzIOWriteAt write_at
Definition: rz_io.h:241
RzIO * io
Definition: rz_io.h:232
RzListFree free
Definition: rz_list.h:21
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58