Пример #1
0
status_t
DisassemblerX8664::GetNextInstructionInfo(InstructionInfo& _info,
	CpuState* state)
{
	unsigned int size = ud_disassemble(fUdisData);
	if (size < 1)
		return B_ENTRY_NOT_FOUND;

	target_addr_t address = ud_insn_off(fUdisData);

	instruction_type type = INSTRUCTION_TYPE_OTHER;
	target_addr_t targetAddress = 0;

	ud_mnemonic_code mnemonic = ud_insn_mnemonic(fUdisData);
	if (mnemonic == UD_Icall)
		type = INSTRUCTION_TYPE_SUBROUTINE_CALL;
	else if (mnemonic == UD_Ijmp)
		type = INSTRUCTION_TYPE_JUMP;
	if (state != NULL)
		targetAddress = GetInstructionTargetAddress(state);

	char buffer[256];
	snprintf(buffer, sizeof(buffer), "0x%016" B_PRIx64 ": %16.16s  %s", address,
		ud_insn_hex(fUdisData), ud_insn_asm(fUdisData));
			// TODO: Resolve symbols!

	if (!_info.SetTo(address, targetAddress, size, type, true, buffer))
		return B_NO_MEMORY;

	return B_OK;
}
Пример #2
0
void Analysis::disasm(pCodeBufferInfo pinfo,std::vector<CodePiece> & code)
{
    ud_t ud_obj;
    ud_init(&ud_obj);

#ifndef PROTECT_X64
    ud_set_mode(&ud_obj,32);
#else
    ud_set_mode(&ud_obj,64);
#endif
    ud_set_pc(&ud_obj,pinfo->addr);
    ud_set_input_buffer(&ud_obj, (uint8_t*)pinfo->buf, pinfo->size);
    ud_set_syntax(&ud_obj,UD_SYN_INTEL);

    base = pinfo->addr;
    size = pinfo->size;
    AddressArray a_array = analysis_code_piece_address(pinfo);

    int point = 0;
    const bool begin = true;
    const bool end = false;
    bool status = end;
    std::map<long,int> addr_id;

    set_label_address(pinfo,a_array,addr_id);
    CodePiece *piece = NULL;
    while (ud_disassemble(&ud_obj) != 0)
    {

        if (ud_obj.insn_offset == a_array[point] && status == end)
        {
            piece = new CodePiece;
            piece->set_label(point);
            point++;
            status = begin;
        }
        if (a_array.get_size() > point)
        {
            if (ud_obj.pc == a_array[point])
            {
                if (addr_id.find(ud_obj.pc) == addr_id.end()) //下条指令没有找到
                {
#ifdef DEBUG
                    printf("没有查找到数据,地址%08x\n",ud_obj.pc)  ;
#endif
                    //piece->set_jmplabel(PC_NONE);
                    if (ud_obj.mnemonic == UD_Iret)
                    {
                        //piece->set_jmplabel(PC_NONE);
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_RET);
                    }
                    else if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                    {
                        long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                        if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size
                                && ud_obj.operand[0].type == UD_OP_JIMM)
                        {
                            piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JMP);
                            piece->set_jmplabel(addr_id[addr]);
                        }
                        else
                        {
                           piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                           if (ud_obj.operand[0].type == UD_OP_JIMM)
                               piece->set_jmplabel(addr);
                           else
                               piece->set_jmplabel(PC_NONE);

                        }
                    }
                    else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                    {
                        long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                        //if (addr >= pinfo->addr && addr <= pinfo->addr + pinfo->size &&
                        if (addr >= pinfo->addr && addr < pinfo->addr + pinfo->size &&
                                ud_obj.operand[0].type == UD_OP_JIMM)
                        {
                            piece->set_opcode_attribute(OPCODE_ATTRIBUTE_CALL);
                            piece->set_jmplabel(addr_id[addr]);
                        }
                        else
                        {
                           piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                           if (ud_obj.operand[0].type == UD_OP_JIMM)
                               piece->set_jmplabel(addr);
                           else
                               piece->set_jmplabel(PC_NONE);
                        }
                    }
                    else
                    {
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXIT);
                        piece->set_jmplabel(ud_obj.pc);
                    }
                }
                else
                {
                    if (ud_obj.operand[0].type == UD_OP_JIMM
                            || ud_obj.mnemonic == UD_Icall
                            || ud_obj.mnemonic == UD_Ijmp)//&& ud_obj.mnemonic != UD_Icall)
                    {
                        piece->set_is_jcc(ud_obj.mnemonic != UD_Icall &&
                                        ud_obj.mnemonic != UD_Iret &&
                                        ud_obj.mnemonic != UD_Ijmp);
                        if (ud_obj.operand[0].type == UD_OP_MEM
                                || ud_obj.operand[0].type == UD_OP_REG)
                        {
                            if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                            {
                                piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                            }
                            else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                            {
                                piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                            }
                            else
                            {
                               //piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                            }
                            piece->set_jmplabel(PC_NONE);
                        }
                        else
                        {
                            long addr = ud_obj.operand[0].size == 8
                                            ? ((signed char)ud_obj.operand[0].lval.sbyte + ud_obj.pc) :
                                    (ud_obj.operand[0].lval.sdword + ud_obj.pc);
                            if (addr >= pinfo->addr && addr < pinfo->addr + pinfo->size) //<=pinfo->addr + pinfo->size将导致跳转到最后一条指令的下一条还是在范围之内
                            {
                                if (addr_id.find(addr) == addr_id.end())
                                {
                                    printf("没有找到跳转地址:%08x\n",addr );
                                }
                                if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JMP);
                                   piece->set_jmplabel(addr_id[addr]);
                                }
                                else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_CALL);
                                   piece->set_jmplabel(addr);
                                }
                                else
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                                   piece->set_jmplabel( addr_id[addr] );
                                }
                            }
                            else
                            {
                                if (ud_insn_mnemonic(&ud_obj) == UD_Ijmp)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_JMP);
                                   //piece->set_jmplabel(addr_id[addr]);
                                }
                                else if (ud_insn_mnemonic(&ud_obj) == UD_Icall)
                                {
                                   piece->set_opcode_attribute(OPCODE_ATTRIBUTE_EXTERNAL_CALL);
                                   //piece->set_jmplabel(addr);
                                }
                                else
                                {
                                   //piece->set_opcode_attribute(OPCODE_ATTRIBUTE_JCC);
                                   printf("jcc不能跳转到虚拟机外部\n");
                                   //piece->set_jmplabel( addr_id[addr] );
                                }
                                piece->set_jmplabel(addr);
                            }
                        }
                    }
                    else
                    {
                        piece->set_jmplabel( addr_id[ud_obj.pc] );
                        piece->set_opcode_attribute(OPCODE_ATTRIBUTE_NORMAL);
                    }
                }
                if (ud_obj.mnemonic == UD_Iret)
                {
                    piece->set_jmplabel(PC_NONE);
                    piece->set_opcode_attribute(OPCODE_ATTRIBUTE_RET);
                    //piece->set_jmplabel(PC_RET);
                }
                piece->add_assemble(ud_obj);
                code.push_back(*piece);
                delete piece;
                piece = NULL;
                status = end;

            }
        }
        if (status == begin)
        {
            if (piece == NULL) {
                printf("没有为piece分配空间");
            }
            piece->add_assemble(ud_obj);
        }

    }
}
Пример #3
0
target_addr_t
DisassemblerX8664::GetInstructionTargetAddress(CpuState* state) const
{
	ud_mnemonic_code mnemonic = ud_insn_mnemonic(fUdisData);
	if (mnemonic != UD_Icall && mnemonic != UD_Ijmp)
		return 0;

	CpuStateX8664* x64State = dynamic_cast<CpuStateX8664*>(state);
	if (x64State == NULL)
		return 0;

	target_addr_t targetAddress = 0;
	const struct ud_operand* op = ud_insn_opr(fUdisData, 0);
	switch (op->type) {
		case UD_OP_REG:
		{
			targetAddress = x64State->IntRegisterValue(
				RegisterNumberFromUdisIndex(op->base));
			targetAddress += op->offset;
		}
		break;
		case UD_OP_MEM:
		{
			targetAddress = x64State->IntRegisterValue(
				RegisterNumberFromUdisIndex(op->base));
			targetAddress += x64State->IntRegisterValue(
				RegisterNumberFromUdisIndex(op->index))
				* op->scale;
			off_t offset = 0;
			switch (op->offset) {
				case 8:
					offset = op->lval.sbyte;
					break;
				case 16:
					offset = op->lval.sword;
					break;
				case 32:
					offset = op->lval.sdword;
					break;
				case 64:
					offset = op->lval.sqword;
					break;
			}
			targetAddress += offset;
		}
		break;
		case UD_OP_JIMM:
		{
			targetAddress = ud_insn_off(fUdisData) + ud_insn_len(fUdisData);
			if (op->size == 32)
				targetAddress += op->lval.sdword;
			else
				targetAddress += op->lval.sqword;
		}
		break;

		case UD_OP_IMM:
		case UD_OP_CONST:
		{
			if (op->size == 32)
				targetAddress = op->lval.udword;
			else if (op->size == 64)
				targetAddress = op->lval.uqword;
		}
		break;

		default:
		break;
	}

	return targetAddress;
}