File: mem.c

package info (click to toggle)
radare2 0.9.6-3.1%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 17,496 kB
  • ctags: 45,959
  • sloc: ansic: 240,999; sh: 3,645; makefile: 2,520; python: 1,212; asm: 312; ruby: 214; awk: 209; perl: 188; lisp: 169; java: 23; xml: 17; php: 6
file content (245 lines) | stat: -rw-r--r-- 5,822 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/* radare - LGPL - Copyright 2007-2013 - pancake */

#include <r_util.h>
#include <stdlib.h>
#if __UNIX__
#include <sys/mman.h>
#endif

// TODO: find better name (r_mem_length()); is this used somewhere?
R_API int r_mem_count(const ut8 **addr) {
	int i = 0;
	while (*addr++)
		i++;
	return i;
}

R_API int r_mem_eq(ut8 *a, ut8 *b, int len) {
	register int i;
	for (i=0; i<len; i++)
		if (a[i] != b[i])
			return R_FALSE;
	return R_TRUE;
}

R_API void r_mem_copyloop(ut8 *dest, const ut8 *orig, int dsize, int osize) {
	int i=0, j;
	while (i<dsize)
		for (j=0; j<osize && i<dsize;j++)
			dest[i++] = orig[j];
}

R_API int r_mem_cmp_mask(const ut8 *dest, const ut8 *orig, const ut8 *mask, int len) {
	int i, ret = -1;
	ut8 *mdest, *morig;
	mdest = malloc (len);
	morig = malloc (len);
	for (i=0; i<len; i++) {
		mdest[i] = dest[i]&mask[i];
		morig[i] = orig[i]&mask[i];
	}
	ret = memcmp (mdest, morig, len);
	free (mdest);
	free (morig);
	return ret;
}

R_API void r_mem_copybits(ut8 *dst, const ut8 *src, int bits) {
	ut8 srcmask, dstmask;
	int bytes = (int)(bits/8);
	bits = bits%8;
	
	memcpy (dst, src, bytes);
	if (bits) {
		srcmask = dstmask = 0;
		switch (bits) {
		case 1: srcmask = 0x80; dstmask = 0x7f; break;
		case 2: srcmask = 0xc0; dstmask = 0x3f; break;
		case 3: srcmask = 0xe0; dstmask = 0x1f; break;
		case 4: srcmask = 0xf0; dstmask = 0x0f; break;
		case 5: srcmask = 0xf8; dstmask = 0x07; break;
		case 6: srcmask = 0xfc; dstmask = 0x03; break;
		case 7: srcmask = 0xfe; dstmask = 0x01; break;
		}
		dst[bytes] = ((dst[bytes]&dstmask) | (src[bytes]&srcmask));
	}
}

// TODO: this method is ugly as shit.
R_API void r_mem_copybits_delta(ut8 *dst, int doff, const ut8 *src, int soff, int bits) {
	int nbits = bits;
#if 0
	int dofb, sofb;
	int bdoff = (doff/8);
	int bsoff = (soff/8);
	int nbits = 0;
	ut8 mask;
	int sdelta = soff-doff;
	/* apply delta offsets */
	src = src+bsoff;
	dst = dst+bdoff;
	dofb=doff%8;
	sofb=soff%8;
	if (sofb||dofb) {
		// TODO : this algorithm is not implemented
		int mask = (1<<sofb);
		int nmask = 0xff^mask;
		int s = src[0]<<sofb;
		int d = dst[0]<<dofb;
		if (soff == doff && bits==1) {
			mask = 0xff^(1<<dofb);
			dst[0] = ((src[0]&mask) | (dst[0]&mask));
		} else printf("TODO: Oops. not supported method of bitcopy\n");
/*
	1) shift algin src i dst
	2) copy (8-dofb) bits from dst to src
	3) dst[0] = dst[0]&^(0x1<<nbits) | (src&(1<<nbits))
*/
		src++;
		dst++;
	}
/*
doff  v
dst |__________|___________|
soff     v
src |__________|_________|
*/
#endif
	r_mem_copybits (dst, src, nbits);
}

R_API ut64 r_mem_get_num(const ut8 *b, int size, int endian) {
        ut16 n16;
        ut32 n32;
        ut64 n64;
        switch (size) {
        case 1: return b[0];
        case 2:
                r_mem_copyendian ((ut8*)&n16, b, 2, endian);
		return (ut64)n16;
        case 4:
                r_mem_copyendian ((ut8*)&n32, b, 4, endian);
		return (ut64)n32;
        case 8:
                r_mem_copyendian ((ut8*)&n64, b, 8, endian);
		return (ut64)n64;
        }
	return 0LL;
}

// TODO: SEE: R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) { .. dupped code?
R_API int r_mem_set_num (ut8 *dest, int dest_size, ut64 num, int endian) {
	int num4;
	short num2;
	switch (dest_size) {
	case 1: dest[0] = (ut8) num;
		break;
	case 2: num2 = (short)num;
		r_mem_copyendian (dest, (const ut8*)&num2, 2, endian);
		break;
	case 4: num4 = (int)num;
		r_mem_copyendian (dest, (const ut8*)&num4, 4, endian);
		break;
	case 8: r_mem_copyendian (dest, (const ut8*)&num, 8, endian);
		break;
	default:
		return R_FALSE;
	}
	return R_TRUE;
}

/* XXX TODO check and use system endian */
// TODO: rename to r_mem_swap() */
R_API void r_mem_copyendian (ut8 *dest, const ut8 *orig, int size, int endian) {
	ut8 buffer[8];
	if (!dest)
		return;
	if (!orig) {
		memset (dest, 0xFF, size);
		return;
	}
        if (endian) {
		if (dest != orig)
			memmove (dest, orig, size);
        } else
	switch (size) {
	case 1:
		*dest = *orig;
		break;
	case 2:
		*buffer = *orig;
		dest[0] = orig[1];
		dest[1] = buffer[0];
		break;
	case 4:
		memcpy (buffer, orig, 4);
		dest[0] = buffer[3];
		dest[1] = buffer[2];
		dest[2] = buffer[1];
		dest[3] = buffer[0];
		break;
	case 8:
		memcpy (buffer, orig, 8);
		dest[0] = buffer[7];
		dest[1] = buffer[6];
		dest[2] = buffer[5];
		dest[3] = buffer[4];
		dest[4] = buffer[3];
		dest[5] = buffer[2];
		dest[6] = buffer[1];
		dest[7] = buffer[0];
		break;
	default:
		if (dest != orig)
			memmove (dest, orig, size);
		//eprintf ("Invalid endian copy of size: %d\n", size);
	}
}

//R_DOC r_mem_mem: Finds the needle of nlen size into the haystack of hlen size
//R_UNIT printf("%s\n", r_mem_mem("food is pure lame", 20, "is", 2));
R_API const ut8 *r_mem_mem(const ut8 *haystack, int hlen, const ut8 *needle, int nlen) {
	int i, until = hlen-nlen+1;
	for (i=0; i<until; i++) {
		if (!memcmp (haystack+i, needle, nlen))
			return haystack+i;
	}
	return NULL;
}

// TODO: implement pack/unpack helpers use vararg or wtf?
R_API int r_mem_pack() {
	// TODO: copy this from r_buf??
	return R_TRUE;
}

R_API int r_mem_unpack(const ut8 *buf) {
	// TODO: copy this from r_buf??
	return R_TRUE;
}

R_API int r_mem_protect(void *ptr, int size, const char *prot) {
#if __UNIX__
	int p = 0;
	if (strchr (prot, 'x')) p |= PROT_EXEC;
	if (strchr (prot, 'r')) p |= PROT_READ;
	if (strchr (prot, 'w')) p |= PROT_WRITE;
	if (mprotect (ptr, size, p)==-1)
		return R_FALSE;
#elif __WINDOWS__
	int r, w, x;
	DWORD p = PAGE_NOACCESS;
	r = strchr (prot, 'r')? 1: 0; 
	w = strchr (prot, 'w')? 1: 0;
	x = strchr (prot, 'x')? 1: 0;;
	if (w && x) return R_FALSE;
	if (x) p = PAGE_EXECUTE_READ;
	else if (w) p = PAGE_READWRITE;
	else if (r) p = PAGE_READONLY;
	if (!VirtualProtect (ptr, size, p, NULL))
		return R_FALSE;
#else
	#warning Unknown platform
#endif
	return R_TRUE;
}