Example #1
0
void test_labels(void) {
    init_hash_table();
    Instruction* i = new_instruction_label("test", 1);
    TEST_ASSERT_EQUAL_STRING("test", i->opcode);
    TEST_ASSERT(i->type = I_TYPE_LABEL);
    set_label_address("test", 34);
    Address* a = addr_from_label(strdup("test"));
    resolve_address(a);
    TEST_ASSERT_EQUAL_INT_MESSAGE(34, a->immediate, "Incorrect label address");
    free(a);
    free(i);
}
Example #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);
        }

    }
}