Пример #1
0
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) {
	ut64 len, check_len;
	int i, j, k, tsize, endian, m = 1;
	if (!b || b->empty) return 0;
	if (addr == R_BUF_CUR)
		addr = b->cur;
	else addr -= b->base;
	if (addr == UT64_MAX || addr > b->length)
		return -1;
	tsize = 2;
	for (i = len = 0; i < n; i++)
	for (j = 0; fmt[j]; j++) {
		switch (fmt[j]) {
		case '0'...'9':
			if (m == 1)
				m = r_num_get (NULL, &fmt[j]);
			continue;
		case 's': tsize = 2; endian = 1; break;
		case 'S': tsize = 2; endian = 0; break;
		case 'i': tsize = 4; endian = 1; break;
		case 'I': tsize = 4; endian = 0; break;
		case 'l': tsize = 8; endian = 1; break;
		case 'L': tsize = 8; endian = 0; break;
		case 'c': tsize = 1; endian = 1; break;
		default: return -1;
		}

		/* Avoid read/write out of bound.
		   tsize and m are not user controled, then don't
		   need to check possible overflow.
		 */
		if (!UT64_ADD (&check_len, len, tsize*m))
			return -1;
		if (!UT64_ADD (&check_len, check_len, addr))
			return -1;
		if (check_len > b->length) {
			return check_len;
			// return -1;
		}

		for (k = 0; k < m; k++) {
			if (write) {
				r_mem_copyendian (
				(ut8*)&buf[addr+len+(k*tsize)],
				(ut8*)&b->buf[len+(k*tsize)],
				tsize, endian);
			} else {
				r_mem_copyendian (
				(ut8*)&buf[len+(k*tsize)],
				(ut8*)&b->buf[addr+len+(k*tsize)],
				tsize, endian);
			}
		}
		len += tsize*m;
		m = 1;
	}
	b->cur = addr + len;
	return len;
}
Пример #2
0
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) {
	ut64 len, check_len;
	int i, j, k, tsize, bigendian, m = 1;
	if (!b || b->empty) return 0;
	if (b->fd != -1) {
		eprintf ("r_buf_fcpy_at not supported yet for r_buf_new_file\n");
		return 0;
	}
	if (addr == R_BUF_CUR)
		addr = b->cur;
	else addr -= b->base;
	if (addr == UT64_MAX || addr > b->length)
		return -1;
	tsize = 2;
	for (i = len = 0; i < n; i++)
	for (j = 0; fmt[j]; j++) {
		switch (fmt[j]) {
		#ifdef _MSC_VER
		case'0':case'1':case'2':case'3':case'4':case'5':case'6':case'7':case'8':case'9':
		#else
		case '0'...'9':
		#endif
			if (m == 1)
				m = r_num_get (NULL, &fmt[j]);
			continue;
		case 's': tsize = 2; bigendian = 0; break;
		case 'S': tsize = 2; bigendian = 1; break;
		case 'i': tsize = 4; bigendian = 0; break;
		case 'I': tsize = 4; bigendian = 1; break;
		case 'l': tsize = 8; bigendian = 0; break;
		case 'L': tsize = 8; bigendian = 1; break;
		case 'c': tsize = 1; bigendian = 0; break;
		default: return -1;
		}

		/* Avoid read/write out of bound.
		   tsize and m are not user controled, then don't
		   need to check possible overflow.
		 */
		if (!UT64_ADD (&check_len, len, tsize*m))
			return -1;
		if (!UT64_ADD (&check_len, check_len, addr))
			return -1;
		if (check_len > b->length) {
			return check_len;
			// return -1;
		}

		for (k = 0; k < m; k++) {
			ut8* src1 = &b->buf[len+(k*tsize)];
			ut8* src2 = &b->buf[addr+len+(k*tsize)];
			void* dest1 = &buf[addr+len+(k*tsize)];
			void* dest2 = &buf[len+(k*tsize)];
			ut8* dest1_8 = (ut8*)dest1;
			ut16* dest1_16 = (ut16*)dest1;
			ut32* dest1_32 = (ut32*)dest1;
			ut64* dest1_64 = (ut64*)dest1;
			ut8* dest2_8 = (ut8*)dest2;
			ut16* dest2_16 = (ut16*)dest2;
			ut32* dest2_32 = (ut32*)dest2;
			ut64* dest2_64 = (ut64*)dest2;
			if (write) {
				switch (tsize) {
				case 1:
					*dest1_8 = r_read_ble8 (src1);
					break;
				case 2:
					*dest1_16 = r_read_ble16 (src1, bigendian);
					break;
				case 4:
					*dest1_32 = r_read_ble32 (src1, bigendian);
					break;
				case 8:
					*dest1_64 = r_read_ble64 (src1, bigendian);
					break;
				}
			} else {
				switch (tsize) {
				case 1:
					*dest2_8 = r_read_ble8 (src2);
					break;
				case 2:
					*dest2_16 = r_read_ble16 (src2, bigendian);
					break;
				case 4:
					*dest2_32 = r_read_ble32 (src2, bigendian);
					break;
				case 8:
					*dest2_64 = r_read_ble64 (src2, bigendian);
					break;
				}
			}
		}
		len += tsize * m;
		m = 1;
	}
	b->cur = addr + len;
	return len;
}