Esempio n. 1
0
/* java_encode */
static int _java_encode(AsmArchPlugin * plugin,
		AsmArchInstruction const * instruction,
		AsmArchInstructionCall * call)
{
	AsmArchPluginHelper * helper = plugin->helper;
	size_t i;
	AsmArchOperandDefinition definitions[3];
	AsmArchOperand * ao;
	uint8_t u8;
	uint16_t u16;
	uint32_t u32;

	if((helper->write(helper->arch, &instruction->opcode, 1)) != 1)
		return -1;
	/* FIXME tableswitch may need some padding */
	definitions[0] = instruction->op1;
	definitions[1] = instruction->op2;
	definitions[2] = instruction->op3;
	for(i = 0; i < call->operands_cnt; i++)
	{
		ao = &call->operands[i];
		if(AO_GET_TYPE(ao->definition) != AOT_IMMEDIATE)
			return -error_set_code(1, "%s", "Not implemented");
		if(AO_GET_SIZE(definitions[i]) == 8)
		{
			u8 = ao->value.immediate.value;
			if(helper->write(helper->arch, &u8, 1) != 1)
				return -1;
		}
		else if(AO_GET_SIZE(definitions[i]) == 16)
		{
			u16 = _htob16(ao->value.immediate.value);
			if(helper->write(helper->arch, &u16, 2) != 2)
				return -1;
		}
		else if(AO_GET_SIZE(definitions[i]) == 32)
		{
			u32 = _htob32(ao->value.immediate.value);
			if(helper->write(helper->arch, &u32, 4) != 4)
				return -1;
		}
		else
			return -error_set_code(1, "%s", "Size not implemented");
	}
	return 0;
}
Esempio n. 2
0
static int _call_operands_immediate(AsmArchOperandDefinition opdefinition,
		AsmArchOperand * operand)
{
	uint64_t value;
	uint32_t size;

	/* check if the size fits */
	value = operand->value.immediate.value;
#if 0 /* XXX ignore for now */
	if((size = AO_GET_SIZE(opdefinition)) > 0
			&& AO_GET_FLAGS(opdefinition) & AOF_SIGNED)
		size--;
#else
	size = AO_GET_SIZE(opdefinition);
#endif
	value >>= size;
	if(value > 0)
		return -1;
	/* check if it is signed */
	if(operand->value.immediate.negative
			&& !(AO_GET_FLAGS(opdefinition) & AOF_SIGNED))
		return -1;
	return 0;
}
Esempio n. 3
0
/* arch_get_instruction_by_opcode */
AsmArchInstruction const * arch_get_instruction_by_opcode(AsmArch * arch,
		uint8_t size, uint32_t opcode)
{
	size_t i;
	AsmArchInstruction const * ai;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(arch, %u, 0x%x)\n", __func__, size, opcode);
#endif
	for(i = 0; i < arch->instructions_cnt; i++)
	{
		ai = &arch->definition->instructions[i];
		if(AO_GET_SIZE(ai->flags) != size)
			continue;
		if(ai->opcode == opcode)
			return ai;
	}
	return NULL;
}
Esempio n. 4
0
static int _call_operands_register(AsmArch * arch,
		AsmArchOperandDefinition opdefinition, AsmArchOperand * operand)
{
	char const * name = operand->value._register.name;
	AsmArchDefinition const * definition;
	uint32_t size;
	AsmArchRegister const * ar;

	/* obtain the size */
	if((definition = arch->definition->definition) != NULL
			&& definition->instruction_size != 0)
		size = definition->instruction_size;
	else
		size = AO_GET_SIZE(opdefinition);
	/* check if it exists */
	if((ar = arch_get_register_by_name_size(arch, name, size)) == NULL)
		return -1;
	/* for implicit instructions it must match */
	if(AO_GET_FLAGS(opdefinition) & AOF_IMPLICIT
			&& AO_GET_VALUE(opdefinition) != ar->id)
		return -1;
	return 0;
}
Esempio n. 5
0
/* java_decode */
static int _java_decode(AsmArchPlugin * plugin, AsmArchInstructionCall * call)
{
	AsmArchPluginHelper * helper = plugin->helper;
	uint8_t u8;
	AsmArchInstruction const * ai;
	size_t i;
	AsmArchOperand * ao;
	uint16_t u16;
	uint32_t u32;
	AsmString * as;
	uint32_t begin;
	uint32_t end;

	if(helper->read(helper->arch, &u8, sizeof(u8)) != sizeof(u8))
		return -1;
	if((ai = helper->get_instruction_by_opcode(helper->arch, 8, u8))
			== NULL)
	{
		call->name = "db";
		call->operands[0].definition = AO_IMMEDIATE(0, 8, 0);
		call->operands[0].value.immediate.name = NULL;
		call->operands[0].value.immediate.value = u8;
		call->operands[0].value.immediate.negative = 0;
		call->operands_cnt = 1;
		return 0;
	}
	call->name = ai->name;
	/* tableswitch may be followed by padding */
	if(ai->opcode == 0xaa && (i = call->offset % 4) > 0
			&& helper->read(helper->arch, &u32, i) != i)
		return -1;
	call->operands[0].definition = ai->op1;
	call->operands[1].definition = ai->op2;
	call->operands[2].definition = ai->op3;
	for(i = 0; i < 3 && AO_GET_TYPE(call->operands[i].definition)
			!= AOT_NONE; i++)
	{
		ao = &call->operands[i];
		if(AO_GET_TYPE(ao->definition) != AOT_IMMEDIATE)
			/* XXX should there be more types? */
			return -error_set_code(1, "%s", "Not implemented");
		if(AO_GET_SIZE(ao->definition) == 8)
		{
			if(helper->read(helper->arch, &u8, 1) != 1)
				return -1;
			ao->value.immediate.value = u8;
		}
		else if(AO_GET_SIZE(ao->definition) == 16)
		{
			if(helper->read(helper->arch, &u16, 2) != 2)
				return -1;
			u16 = _htob16(u16);
			ao->value.immediate.value = u16;
		}
		else if(AO_GET_SIZE(ao->definition) == 32)
		{
			if(helper->read(helper->arch, &u32, 4) != 4)
				return -1;
			u32 = _htob32(u32);
			ao->value.immediate.value = u32;
		}
		else
			return -error_set_code(1, "%s", "Size not implemented");
		ao->value.immediate.name = NULL;
		ao->value.immediate.negative = 0;
		switch(AO_GET_VALUE(ao->definition))
		{
			case AOI_REFERS_FUNCTION:
			case AOI_REFERS_STRING:
				as = helper->get_string_by_id(helper->arch,
						ao->value.immediate.value);
				if(as != NULL)
					ao->value.immediate.name = as->name;
				ao->value.immediate.negative = 0;
				break;
		}
	}
	call->operands_cnt = i;
	/* tableswitch may be followed by offsets */
	if(ai->opcode == 0xaa)
	{
		for(begin = call->operands[1].value.immediate.value,
				end = call->operands[2].value.immediate.value;
				begin <= end; begin++)
			if(helper->read(helper->arch, &u32, sizeof(u32))
					!= (ssize_t)sizeof(u32))
				return -1;
	}
	return 0;
}