Exemplo n.º 1
0
Arquivo: mz.c Projeto: agatti/radare2
ut64 r_bin_mz_get_main_vaddr(struct r_bin_mz_obj_t *bin) {
	int entry;
	int n;
	ut8 b[512];
	if (!bin || !bin->b) {
		return 0LL;
	}
	entry = r_bin_mz_get_entrypoint (bin);
	ZERO_FILL (b);
	if (r_buf_read_at (bin->b, entry, b, sizeof (b)) < 0) {
		eprintf ("Warning: Cannot read entry at 0x%08"PFMT32x "\n", (ut32) entry);
		return 0LL;
	}
	// MSVC
	if (b[0] == 0xb4 && b[1] == 0x30) {
		// ff 36 XX XX			push	XXXX
		// ff 36 XX XX			push	argv
		// ff 36 XX XX			push	argc
		// 9a XX XX XX XX		lcall	_main
		// 50				push	ax
		for (n = 0; n < sizeof (b) - 18; n++) {
			if (b[n] == 0xff && b[n + 4] == 0xff && b[n + 8] == 0xff && b[n + 12] == 0x9a && b[n + 17] == 0x50) {
				const ut16 call_addr = r_read_ble16 (b + n + 13, 0);;
				const ut16 call_seg = r_read_ble16 (b + n + 15, 0);;
				const ut64 call_dst = r_bin_mz_seg_to_paddr (bin, call_seg) + call_addr;
				return call_dst;
			}
		}
	}

	return 0LL;
}
Exemplo n.º 2
0
Arquivo: mz.c Projeto: agatti/radare2
int r_bin_mz_get_entrypoint (const struct r_bin_mz_obj_t *bin) {
#if 0
	ut16 cs = r_read_ble16 (buf + 0x16, false);
	ut16 ip = r_read_ble16 (buf + 0x14, false);
	ut16 pa = ((r_read_ble16 (buf + 8 , false) + cs) << 4) + ip;
#endif
	/* Value of CS in DOS header may be negative */
	const short cs = bin->dos_header->cs;
	ut32 pa = bin->dos_header->header_paragraphs + cs;
	const ut32 paddr = (pa<<4) + bin->dos_header->ip;
	if (paddr < bin->dos_file_size) {
		return paddr;
	}
	return -1;
}
Exemplo n.º 3
0
static bool checkEntrypoint(const ut8 *buf, ut64 length) {
	st16 cs = r_read_ble16 (buf + 0x16, false);
	ut16 ip = r_read_ble16 (buf + 0x14, false);
	ut32 pa = ((r_read_ble16 (buf + 8 , false) + cs) << 4) + ip;

	/* A minimal MZ header is 0x1B bytes.  Header length is measured in
	 * 16-byte paragraphs so the minimum header must occupy 2 paragraphs.
	 * This means that the entrypoint should be at least 0x20 unless someone
	 * cleverly fit a few instructions inside the header.
	 */
	pa &= 0xffff;
	if (pa >= 0x20 && pa + 1 < length) {
		ut16 pe = r_read_ble16 (buf + 0x3c, false);
		if (pe < length && length > 0x104 && !memcmp (buf + pe, "PE", 2)) {
			return false;
		}
		return true;
	}
	return false;
}
Exemplo n.º 4
0
static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) {
	const int no_alias = 1;
	struct riscv_opcode *o = NULL;
	ut64 word = 0;
	int xlen = anal->bits;

	op->size = 4;
	op->addr = addr;
	op->type = R_ANAL_OP_TYPE_UNK;

	word = (len >= sizeof (ut64))? r_read_ble64 (data, anal->big_endian): r_read_ble16 (data, anal->big_endian);

	o = get_opcode (word);
	if (word == UT64_MAX) {
		op->type = R_ANAL_OP_TYPE_ILL;
		return -1;
	}
	if (!o || !o->name) return op->size;

	for (; o < &riscv_opcodes[NUMOPCODES]; o++) {
		// XXX ASAN segfault if ( !(o->match_func)(o, word) ) continue;
		if ( no_alias && (o->pinfo & INSN_ALIAS) ) continue;
		if ( isdigit ((int)(o->subset[0])) && atoi (o->subset) != xlen) continue;
		else {
			break;
		}
	}

	if (!o || !o->name) {
		return -1;
	}
// branch/jumps/calls/rets
	if (is_any ("jal")) {
		// decide wether it's ret or call
		int rd = (word >> OP_SH_RD) & OP_MASK_RD;
		op->type = (rd == 0) ? R_ANAL_OP_TYPE_RET: R_ANAL_OP_TYPE_CALL;
		op->jump = EXTRACT_UJTYPE_IMM (word) + addr;
		op->fail = addr + 4;
	} else if (is_any ("jr")) {
Exemplo n.º 5
0
static bool check_bytes(const ut8 *buf, ut64 length) {
	ut16 new_exe_header_offset;
	if (!buf || length <= 0x3d) {
		return false;
	}

	// Check for MZ magic.
	if (memcmp (buf, "MZ", 2) && memcmp (buf, "ZM", 2)) {
		return false;
	}

	// See if there is a new exe header.
	new_exe_header_offset = r_read_ble16 (buf + 0x3c, false);
	if (length > new_exe_header_offset + 2) {
		// check for PE
		if (!memcmp (buf + new_exe_header_offset, "PE", 2) &&
		    (length > new_exe_header_offset + 0x20) &&
		    !memcmp (buf + new_exe_header_offset + 0x18, "\x0b\x01", 2)) {
			return false;
		}

		// Check for New Executable, LE/LX or Phar Lap executable
		if (!memcmp (buf + new_exe_header_offset, "NE", 2) ||
		    !memcmp (buf + new_exe_header_offset, "LE", 2) ||
		    !memcmp (buf + new_exe_header_offset, "LX", 2) ||
		    !memcmp (buf + new_exe_header_offset, "PL", 2)) {
			if (!checkEntrypoint (buf, length)) {
				return false;
			}
		}
	}

	// Raw plain MZ executable (watcom)
	if (!checkEntrypoint (buf, length)) {
		return false;
	}

	return true;
}
Exemplo n.º 6
0
Arquivo: buf.c Projeto: P4N74/radare2
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;
}
Exemplo n.º 7
0
R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) {
	RRegSet *regset;
	int off;
	ut64 ret = 0LL;
	if (!reg || !item) {
		return 0LL;
	}
	off = BITS2BYTES (item->offset);
	regset = &reg->regset[item->arena];
	switch (item->size) {
	case 1:
		{
		int offset = item->offset / 8;
		if (offset + item->size >= regset->arena->size) {
			break;
		}
		ret = (regset->arena->bytes[offset] &
		       (1 << (item->offset % 8))) ? 1 : 0;
		}
		break;
	case 4:
		if (regset->arena->size - off - 1 >= 0) {
			ret = (r_read_at_ble8 (regset->arena->bytes, off)) & 0xF;
		}
		break;
	case 8:
		if (regset->arena->size - off - 1 >= 0) {
			ret = r_read_at_ble8 (regset->arena->bytes, off);
		}
		break;
	case 16:
		if (regset->arena->size - off - 2 >= 0) {
			ret = r_read_ble16 (regset->arena->bytes + off, reg->big_endian);
		}
		break;
	case 27:
		if (off + 3 < regset->arena->size) {
			ret = r_read_me27 (regset->arena->bytes + off, 0);
		}
		break;
	case 32:
		if (off + 4 <= regset->arena->size) {
			ret = r_read_ble32 (regset->arena->bytes + off, reg->big_endian);
		} else {
			eprintf ("r_reg_get_value: 32bit oob read %d\n", off);
		}
		break;
	case 64:
		if (regset->arena->bytes && (off + 8 <= regset->arena->size)) {
			ret = r_read_ble64 (regset->arena->bytes + off, reg->big_endian);
		} else {
			eprintf ("r_reg_get_value: null or oob arena for current regset\n");
		}
		break;
	case 80: // long double
	case 96: // long floating value
		// FIXME: It is a precision loss, please implement me properly!
		ret = (ut64)r_reg_get_longdouble (reg, item);
		break;
	default:
		eprintf ("r_reg_get_value: Bit size %d not supported\n", item->size);
		break;
	}
	return ret;
}