Rizin
unix-like reverse engineering framework and cli tools
mem.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2007-2020 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #if __UNIX__
6 #include <sys/mman.h>
7 #elif __WINDOWS__
8 #include <rz_windows.h>
9 #endif
10 
11 #define SET_BIT(p, n) ((p) |= (1 << (n)))
12 #define CLR_BIT(p, n) ((p) &= (~(1) << (n)))
13 
14 // TODO: find better name (rz_mem_length()); is this used somewhere?
15 RZ_API int rz_mem_count(const ut8 **addr) {
16  int i = 0;
17  while (*addr++) {
18  i++;
19  }
20  return i;
21 }
22 
31 RZ_API int rz_mem_eq(const ut8 *a, const ut8 *b, int len) {
32  register int i;
33  for (i = 0; i < len; i++) {
34  if (a[i] != b[i]) {
35  return false;
36  }
37  }
38  return true;
39 }
40 
41 RZ_API void rz_mem_copyloop(ut8 *dest, const ut8 *orig, int dsize, int osize) {
42  int i = 0, j;
43  while (i < dsize) {
44  for (j = 0; j < osize && i < dsize; j++) {
45  dest[i++] = orig[j];
46  }
47  }
48 }
49 
50 RZ_API void *rz_mem_copy(void *dest, size_t dmax, const void *src, size_t smax) {
51  if (!smax || !dmax) {
52  return NULL;
53  }
55  return memcpy(dest, src, (smax < dmax) ? smax : dmax);
56 }
57 
58 RZ_API int rz_mem_cmp_mask(const ut8 *dest, const ut8 *orig, const ut8 *mask, int len) {
59  ut8 *mdest = malloc(len);
60  if (!mdest) {
61  return -1;
62  }
63  ut8 *morig = malloc(len);
64  if (!morig) {
65  free(mdest);
66  return -1;
67  }
68  int i;
69  for (i = 0; i < len; i++) {
70  mdest[i] = dest[i] & mask[i];
71  morig[i] = orig[i] & mask[i];
72  }
73  int ret = memcmp(mdest, morig, len);
74  free(mdest);
75  free(morig);
76  return ret;
77 }
78 
79 RZ_API void rz_mem_copybits(ut8 *dst, const ut8 *src, int bits) {
80  ut8 srcmask, dstmask;
81  int bytes = (int)(bits / 8);
82  bits = bits % 8;
83  memcpy(dst, src, bytes);
84  if (bits) {
85  srcmask = dstmask = 0;
86  switch (bits) {
87  case 1:
88  srcmask = 0x80;
89  dstmask = 0x7f;
90  break;
91  case 2:
92  srcmask = 0xc0;
93  dstmask = 0x3f;
94  break;
95  case 3:
96  srcmask = 0xe0;
97  dstmask = 0x1f;
98  break;
99  case 4:
100  srcmask = 0xf0;
101  dstmask = 0x0f;
102  break;
103  case 5:
104  srcmask = 0xf8;
105  dstmask = 0x07;
106  break;
107  case 6:
108  srcmask = 0xfc;
109  dstmask = 0x03;
110  break;
111  case 7:
112  srcmask = 0xfe;
113  dstmask = 0x01;
114  break;
115  }
116  dst[bytes] = ((dst[bytes] & dstmask) | (src[bytes] & srcmask));
117  }
118 }
119 
120 static inline char readbit(const ut8 *src, int bitoffset) {
121  const int wholeBytes = bitoffset / 8;
122  const int remainingBits = bitoffset % 8;
123  // return (src[wholeBytes] >> remainingBits) & 1;
124  return (src[wholeBytes] & 1 << remainingBits);
125 }
126 
127 static inline void writebit(ut8 *dst, int i, bool c) {
128  const int byte = i / 8;
129  const int bit = (i % 8);
130  // eprintf ("Write %d %d = %d\n", byte, bit, c);
131  dst += byte;
132  if (c) {
133  // dst[byte] |= (1 << bit);
134  RZ_BIT_SET(dst, bit);
135  } else {
136  // dst[byte] &= (1 << bit);
137  RZ_BIT_UNSET(dst, bit);
138  }
139 }
140 
141 RZ_API void rz_mem_copybits_delta(ut8 *dst, int doff, const ut8 *src, int soff, int bits) {
142  int i;
143  if (doff < 0 || soff < 0 || !dst || !src) {
144  return;
145  }
146  for (i = 0; i < bits; i++) {
147  bool c = readbit(src, i + soff);
148  writebit(dst, i + doff, c);
149  }
150 }
151 
153  // LITTLE ENDIAN is the default for streams
154  switch (size) {
155  case 1:
156  return rz_read_le8(b);
157  case 2:
158  return rz_read_le16(b);
159  case 4:
160  return rz_read_le32(b);
161  case 8:
162  return rz_read_le64(b);
163  }
164  return 0LL;
165 }
166 
167 // TODO: SEE: RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item) { .. dupped code?
168 RZ_API int rz_mem_set_num(ut8 *dest, int dest_size, ut64 num) {
169  // LITTLE ENDIAN is the default for streams
170  switch (dest_size) {
171  case 1:
173  break;
174  case 2:
176  break;
177  case 4:
179  break;
180  case 8:
182  break;
183  default:
184  return false;
185  }
186  return true;
187 }
188 
189 // The default endian is LE for streams.
190 // This function either swaps or copies len bytes depending on bool big_endian
191 // TODO: Remove completely
192 RZ_API void rz_mem_swaporcopy(ut8 *dest, const ut8 *src, int len, bool big_endian) {
193  if (big_endian) {
195  } else {
196  memcpy(dest, src, len);
197  }
198 }
199 
200 // This function unconditionally swaps endian of size bytes of orig -> dest
201 // TODO: Remove completely
202 RZ_API void rz_mem_swapendian(ut8 *dest, const ut8 *orig, int size) {
203  ut8 buffer[8];
204  switch (size) {
205  case 1:
206  *dest = *orig;
207  break;
208  case 2:
209  *buffer = *orig;
210  dest[0] = orig[1];
211  dest[1] = buffer[0];
212  break;
213  case 3:
214  *buffer = *orig;
215  dest[0] = orig[2];
216  dest[1] = orig[1];
217  dest[2] = buffer[0];
218  break;
219  case 4:
220  memcpy(buffer, orig, 4);
221  dest[0] = buffer[3];
222  dest[1] = buffer[2];
223  dest[2] = buffer[1];
224  dest[3] = buffer[0];
225  break;
226  case 8:
227  memcpy(buffer, orig, 8);
228  dest[0] = buffer[7];
229  dest[1] = buffer[6];
230  dest[2] = buffer[5];
231  dest[3] = buffer[4];
232  dest[4] = buffer[3];
233  dest[5] = buffer[2];
234  dest[6] = buffer[1];
235  dest[7] = buffer[0];
236  break;
237  default:
238  if (dest != orig) {
239  memmove(dest, orig, size);
240  }
241  }
242 }
243 
244 // RZ_DOC rz_mem_mem: Finds the needle of nlen size into the haystack of hlen size
245 // RZ_UNIT printf("%s\n", rz_mem_mem("food is pure lame", 20, "is", 2));
246 RZ_API const ut8 *rz_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int nlen) {
247  int i, until = hlen - nlen + 1;
248  if (hlen < 1 || nlen < 1) {
249  return NULL;
250  }
251  for (i = 0; i < until; i++) {
252  if (!memcmp(haystack + i, needle, nlen)) {
253  return haystack + i;
254  }
255  }
256  return NULL;
257 }
258 
259 // TODO: rename to rz_mem_mem and refactor all calls to this function
260 RZ_API const ut8 *rz_mem_mem_aligned(const ut8 *haystack, int hlen, const ut8 *needle, int nlen, int align) {
261  int i, until = hlen - nlen + 1;
262  if (align < 1) {
263  align = 1;
264  }
265  if (hlen < 1 || nlen < 1) {
266  return NULL;
267  }
268  if (align > 1) {
269  until -= (until % align);
270  }
271  for (i = 0; i < until; i += align) {
272  if (!memcmp(haystack + i, needle, nlen)) {
273  return haystack + i;
274  }
275  }
276  return NULL;
277 }
278 
279 RZ_API int rz_mem_protect(void *ptr, int size, const char *prot) {
280 #if __UNIX__
281  int p = 0;
282  if (strchr(prot, 'x')) {
283  p |= PROT_EXEC;
284  }
285  if (strchr(prot, 'r')) {
286  p |= PROT_READ;
287  }
288  if (strchr(prot, 'w')) {
289  p |= PROT_WRITE;
290  }
291  if (mprotect(ptr, size, p) == -1) {
292  return false;
293  }
294 #elif __WINDOWS__
295  int r, w, x;
296  DWORD p = PAGE_NOACCESS;
297  r = strchr(prot, 'r') ? 1 : 0;
298  w = strchr(prot, 'w') ? 1 : 0;
299  x = strchr(prot, 'x') ? 1 : 0;
300  if (w && x) {
301  return false;
302  }
303  if (x) {
304  p = PAGE_EXECUTE_READ;
305  } else if (w) {
306  p = PAGE_READWRITE;
307  } else if (r) {
308  p = PAGE_READONLY;
309  }
310  if (!VirtualProtect(ptr, size, p, NULL)) {
311  return false;
312  }
313 #else
314 #warning Unknown platform
315 #endif
316  return true;
317 }
318 
319 RZ_API void *rz_mem_dup(const void *s, int l) {
320  void *d = malloc(l);
321  if (d) {
322  memcpy(d, s, l);
323  }
324  return d;
325 }
326 
327 RZ_API void rz_mem_reverse(ut8 *b, int l) {
328  ut8 tmp;
329  int i, end = l / 2;
330  for (i = 0; i < end; i++) {
331  tmp = b[i];
332  b[i] = b[l - i - 1];
333  b[l - i - 1] = tmp;
334  }
335 }
336 
337 RZ_API bool rz_mem_is_printable(const ut8 *a, int la) {
338  int i;
339  for (i = 0; i < la; i++) {
340  if (a[i] != '\n' && a[i] != '\t' && !IS_PRINTABLE(a[i])) {
341  return false;
342  }
343  }
344  return true;
345 }
346 
347 RZ_API bool rz_mem_is_zero(const ut8 *b, int l) {
348  int i;
349  for (i = 0; i < l; i++) {
350  if (b[i]) {
351  return false;
352  }
353  }
354  return true;
355 }
356 
357 RZ_API void *rz_mem_alloc(int sz) {
358  return calloc(sz, 1);
359 }
360 
361 RZ_API void rz_mem_free(void *p) {
362  free(p);
363 }
364 
365 RZ_API void rz_mem_memzero(void *dst, size_t l) {
366 #ifdef _MSC_VER
367  RtlSecureZeroMemory(dst, l);
368 #else
369 #if HAVE_EXPLICIT_BZERO
370  explicit_bzero(dst, l);
371 #elif HAVE_EXPLICIT_MEMSET
372  (void)explicit_memset(dst, 0, l);
373 #else
374  memset(dst, 0, l);
375  __asm__ volatile("" ::"r"(dst)
376  : "memory");
377 #endif
378 #endif
379 }
size_t len
Definition: 6502dis.c:15
#define mask()
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
static ut8 bytes[32]
Definition: asm_arc.c:23
int bits(struct state *s, int need)
Definition: blast.c:72
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RzCryptoSelector bit
Definition: crypto.c:16
#define r
Definition: crypto_rc6.c:12
#define w
Definition: crypto_rc6.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 mprotect
Definition: sflib.h:71
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * malloc(size_t size)
Definition: malloc.c:123
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 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 prot
Definition: sflib.h:115
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
char * dst
Definition: lz4.h:724
char * dest
Definition: lz4.h:697
int x
Definition: mipsasm.c:20
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static void rz_write_le32(void *dest, ut32 val)
Definition: rz_endian.h:256
static void rz_write_le16(void *dest, ut16 val)
Definition: rz_endian.h:222
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239
static ut8 rz_read_le8(const void *src)
Definition: rz_endian.h:187
static ut64 rz_read_le64(const void *src)
Definition: rz_endian.h:266
static void rz_write_le64(void *dest, ut64 val)
Definition: rz_endian.h:277
static void rz_write_le8(void *dest, ut8 val)
Definition: rz_endian.h:198
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10
#define RZ_BIT_SET(x, y)
Definition: rz_types.h:311
#define RZ_BIT_UNSET(x, y)
Definition: rz_types.h:312
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT8_MAX
#define UT16_MAX
static int
Definition: sfsocketcall.h:114
#define PROT_READ
Definition: sftypes.h:95
#define PROT_WRITE
Definition: sftypes.h:96
#define PROT_EXEC
Definition: sftypes.h:97
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
#define a(i)
Definition: sha256.c:41
Definition: buffer.h:15
RZ_API int rz_mem_protect(void *ptr, int size, const char *prot)
Definition: mem.c:279
RZ_API bool rz_mem_is_printable(const ut8 *a, int la)
Definition: mem.c:337
RZ_API void rz_mem_reverse(ut8 *b, int l)
Definition: mem.c:327
RZ_API void rz_mem_copybits_delta(ut8 *dst, int doff, const ut8 *src, int soff, int bits)
Definition: mem.c:141
RZ_API void * rz_mem_copy(void *dest, size_t dmax, const void *src, size_t smax)
Definition: mem.c:50
RZ_API void rz_mem_swapendian(ut8 *dest, const ut8 *orig, int size)
Definition: mem.c:202
RZ_API void * rz_mem_dup(const void *s, int l)
Definition: mem.c:319
RZ_API int rz_mem_cmp_mask(const ut8 *dest, const ut8 *orig, const ut8 *mask, int len)
Definition: mem.c:58
static void writebit(ut8 *dst, int i, bool c)
Definition: mem.c:127
static char readbit(const ut8 *src, int bitoffset)
Definition: mem.c:120
RZ_API int rz_mem_eq(const ut8 *a, const ut8 *b, int len)
Compares memory a with b over len bytes.
Definition: mem.c:31
RZ_API void rz_mem_copyloop(ut8 *dest, const ut8 *orig, int dsize, int osize)
Definition: mem.c:41
RZ_API int rz_mem_set_num(ut8 *dest, int dest_size, ut64 num)
Definition: mem.c:168
RZ_API void rz_mem_free(void *p)
Definition: mem.c:361
RZ_API void rz_mem_copybits(ut8 *dst, const ut8 *src, int bits)
Definition: mem.c:79
RZ_API const ut8 * rz_mem_mem_aligned(const ut8 *haystack, int hlen, const ut8 *needle, int nlen, int align)
Definition: mem.c:260
RZ_API void * rz_mem_alloc(int sz)
Definition: mem.c:357
RZ_API void rz_mem_swaporcopy(ut8 *dest, const ut8 *src, int len, bool big_endian)
Definition: mem.c:192
RZ_API void rz_mem_memzero(void *dst, size_t l)
Definition: mem.c:365
RZ_API const ut8 * rz_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int nlen)
Definition: mem.c:246
RZ_API bool rz_mem_is_zero(const ut8 *b, int l)
Definition: mem.c:347
RZ_API int rz_mem_count(const ut8 **addr)
Definition: mem.c:15
RZ_API ut64 rz_mem_get_num(const ut8 *b, int size)
Definition: mem.c:152
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
DWORD
static int addr
Definition: z80asm.c:58