예제 #1
0
 public static bool get_operand_displacement(OPERAND op, ref uint disp)
 {
     if (op.dispbytes != 0)
     {
         disp = op.displacement;
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #2
0
 public static bool get_destination_operand(INSTRUCTION inst, ref OPERAND op)
 {
     if (inst.op1.type != OperandType.OPERAND_TYPE_NONE)
     {
         op = inst.op1;
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #3
0
 public static bool get_operand_immediate(OPERAND op, ref uint imm)
 {
     if (op.immbytes != 0)
     {
         imm = op.immediate;
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #4
0
        public static uint get_register_type(OPERAND op)
        {
            if (op.type != OperandType.OPERAND_TYPE_REGISTER)
            {
                return(0);
            }
            switch (Macros.MASK_AM(op.flags))
            {
            case Consts.AM_REG:
                if (Macros.MASK_FLAGS(op.flags) == Consts.F_r)
                {
                    return(Consts.REGISTER_TYPE_SEGMENT);
                }
                else if (Macros.MASK_FLAGS(op.flags) == Consts.F_f)
                {
                    return(Consts.REGISTER_TYPE_FPU);
                }
                else
                {
                    return(Consts.REGISTER_TYPE_GEN);
                }

            case Consts.AM_E:
            case Consts.AM_G:
            case Consts.AM_R:
                return(Consts.REGISTER_TYPE_GEN);

            case Consts.AM_C:
                return(Consts.REGISTER_TYPE_CONTROL);

            case Consts.AM_D:
                return(Consts.REGISTER_TYPE_DEBUG);

            case Consts.AM_S:
                return(Consts.REGISTER_TYPE_SEGMENT);

            case Consts.AM_T:
                return(Consts.REGISTER_TYPE_TEST);

            case Consts.AM_P:
            case Consts.AM_Q:
                return(Consts.REGISTER_TYPE_MMX);

            case Consts.AM_V:
            case Consts.AM_W:
                return(Consts.REGISTER_TYPE_XMM);

            default:
                break;
            }
            return(0);
        }
예제 #5
0
        public static string get_operand_string(INSTRUCTION inst, OPERAND op, Format format, uint offset)
        {
            StringBuilder ret = new StringBuilder();

            Mode mode;
            uint regtype = 0;
            uint tmp     = 0;

            if (op.type == OperandType.OPERAND_TYPE_REGISTER)
            {
                mode = MODE_CHECK_OPERAND(inst.mode, inst.flags);

                if (format == Format.FORMAT_ATT)
                {
                    ret.Append("%%");
                }


                switch (Macros.MASK_AM(op.flags))
                {
                case Consts.AM_REG:
                    if (Macros.MASK_FLAGS(op.flags) == Consts.F_r)
                    {
                        regtype = Consts.REG_SEGMENT;
                    }
                    else if (Macros.MASK_FLAGS(op.flags) == Consts.F_f)
                    {
                        regtype = Consts.REG_FPU;
                    }
                    else
                    {
                        regtype = Consts.REG_GEN_DWORD;
                    }
                    break;

                case Consts.AM_E:
                case Consts.AM_G:
                case Consts.AM_R:
                    regtype = Consts.REG_GEN_DWORD;
                    break;

                case Consts.AM_C:
                    regtype = Consts.REG_CONTROL;
                    break;

                case Consts.AM_D:
                    regtype = Consts.REG_DEBUG;
                    break;

                case Consts.AM_S:
                    regtype = Consts.REG_SEGMENT;
                    break;

                case Consts.AM_T:
                    regtype = Consts.REG_TEST;
                    break;

                case Consts.AM_P:
                case Consts.AM_Q:
                    regtype = Consts.REG_MMX;
                    break;

                case Consts.AM_V:
                case Consts.AM_W:
                    regtype = Consts.REG_XMM;
                    break;
                }
                if (regtype == Consts.REG_GEN_DWORD)
                {
                    switch (Macros.MASK_OT(op.flags))
                    {
                    case Consts.OT_b:
                        ret.Append(Consts.reg_table[Consts.REG_GEN_BYTE, op.reg]);
                        break;

                    case Consts.OT_v:
                        ret.Append((mode == Mode.MODE_32) ? Consts.reg_table[Consts.REG_GEN_DWORD, op.reg] : Consts.reg_table[Consts.REG_GEN_WORD, op.reg]);
                        break;

                    case Consts.OT_w:
                        ret.Append(Consts.reg_table[Consts.REG_GEN_WORD, op.reg]);
                        break;

                    case Consts.OT_d:
                        ret.Append(Consts.reg_table[Consts.REG_GEN_DWORD, op.reg]);
                        break;
                    }
                }
                else
                {
                    ret.Append(Consts.reg_table[regtype, op.reg]);
                }
            }
            else if (op.type == OperandType.OPERAND_TYPE_MEMORY)
            {
                mode = MODE_CHECK_ADDR(inst.mode, inst.flags);


                if (Macros.MASK_PREFIX_G2(inst.flags) != 0)
                {
                    ret.AppendFormat("{0}{1}:", (format == Format.FORMAT_ATT) ? "%" : "", Consts.reg_table[Consts.REG_SEGMENT, (Macros.MASK_PREFIX_G2(inst.flags)) - 1]);
                }

                if (format == Format.FORMAT_ATT)
                {
                    if (Macros.MASK_PERMS(op.flags) == Consts.P_x)
                    {
                        ret.Append("*");
                    }


                    if (op.dispbytes != 0)
                    {
                        ret.AppendFormat("0x{0:X}", op.displacement);
                    }


                    if ((op.basereg == Consts.REG_NOP) && (op.indexreg == Consts.REG_NOP))
                    {
                        return(ret.ToString());
                    }
                }

                ret.Append((format == Format.FORMAT_ATT) ? "(" : "[");


                if (op.basereg != Consts.REG_NOP)
                {
                    ret.AppendFormat("{0}{1}", (format == Format.FORMAT_ATT) ? "%" : "", (mode == Mode.MODE_32) ? Consts.reg_table[Consts.REG_GEN_DWORD, op.basereg] : Consts.reg_table[Consts.REG_GEN_WORD, op.basereg]);
                }

                if (op.indexreg != Consts.REG_NOP)
                {
                    if (op.basereg != Consts.REG_NOP)
                    {
                        ret.AppendFormat("{0}{1}", (format == Format.FORMAT_ATT) ? ",%" : "+", (mode == Mode.MODE_32) ? Consts.reg_table[Consts.REG_GEN_DWORD, op.indexreg] : Consts.reg_table[Consts.REG_GEN_WORD, op.indexreg]);
                    }
                    else
                    {
                        ret.AppendFormat("{0}{1}", (format == Format.FORMAT_ATT) ? "%" : "", (mode == Mode.MODE_32) ? Consts.reg_table[Consts.REG_GEN_DWORD, op.indexreg] : Consts.reg_table[Consts.REG_GEN_WORD, op.indexreg]);
                    }
                    switch (op.scale)
                    {
                    case 2:
                        ret.Append((format == Format.FORMAT_ATT) ? ",2" : "*2");
                        break;

                    case 4:
                        ret.Append((format == Format.FORMAT_ATT) ? ",4" : "*4");
                        break;

                    case 8:
                        ret.Append((format == Format.FORMAT_ATT) ? ",8" : "*8");
                        break;
                    }
                }

                if (inst.dispbytes != 0 && (format != Format.FORMAT_ATT))
                {
                    if ((op.basereg != Consts.REG_NOP) || (op.indexreg != Consts.REG_NOP))
                    {
                        if ((op.displacement & (1 << (int)(op.dispbytes * 8 - 1))) != 0)
                        {
                            tmp = op.displacement;
                            switch (op.dispbytes)
                            {
                            case 1:
                                tmp = ~tmp & 0xff;
                                break;

                            case 2:
                                tmp = ~tmp & 0xffff;
                                break;

                            case 4:
                                tmp = ~tmp;
                                break;
                            }
                            ret.AppendFormat("-0x{0:X}", tmp + 1);
                        }
                        else
                        {
                            ret.AppendFormat("+0x{0:X}", op.displacement);
                        }
                    }
                    else
                    {
                        ret.AppendFormat("0x{0:X}", op.displacement);
                    }
                }

                ret.Append((format == Format.FORMAT_ATT) ? ")" : "]");
            }
            else if (op.type == OperandType.OPERAND_TYPE_IMMEDIATE)
            {
                switch (Macros.MASK_AM(op.flags))
                {
                case Consts.AM_J:
                    ret.AppendFormat("0x{0:X}", op.immediate + inst.length + offset);
                    break;

                case Consts.AM_I1:
                case Consts.AM_I:
                    if (format == Format.FORMAT_ATT)
                    {
                        ret.Append("$");
                    }
                    ret.AppendFormat("0x{0:X}", op.immediate);
                    break;

                case Consts.AM_A:
                    ret.AppendFormat("{0}0x{1:X}:{2}0x{2:X}", (format == Format.FORMAT_ATT) ? "$" : "", op.section, (format == Format.FORMAT_ATT) ? "$" : "", op.displacement);
                    break;
                }
            }
            else
            {
                return(null);
            }

            return(ret.ToString());
        }
예제 #6
0
        private static bool get_operand(INST inst, uint oflags, INSTRUCTION instruction, out OPERAND op, byte[] data, uint idx, Mode mode, uint iflags)
        {
            uint index     = 0;
            bool sib       = false;
            uint scale     = 0;
            uint reg       = Consts.REG_NOP;
            uint basereg   = Consts.REG_NOP;
            uint indexreg  = Consts.REG_NOP;
            uint dispbytes = 0;
            Mode pmode;

            op = new OPERAND();

            if (oflags == Consts.FLAGS_NONE)
            {
                op.type = OperandType.OPERAND_TYPE_NONE;
                return(true);
            }

            op.flags = oflags;


            op.reg      = Consts.REG_NOP;
            op.basereg  = Consts.REG_NOP;
            op.indexreg = Consts.REG_NOP;


            op.dispoffset = 0;
            op.immoffset  = 0;


            if (inst.modrm)
            {
                pmode = MODE_CHECK_ADDR(mode, iflags);


                if (instruction.length == 0)
                {
                    instruction.modrm   = (byte)idx;
                    instruction.length += 1;
                }

                reg = Macros.MASK_MODRM_REG(data[idx]);



                if (Macros.MASK_MODRM_MOD(data[idx]) == 0)
                {
                    if ((pmode == Mode.MODE_32) && (Macros.MASK_MODRM_RM(data[idx]) == Consts.REG_EBP))
                    {
                        dispbytes = 4;
                    }
                    if ((pmode == Mode.MODE_16) && (Macros.MASK_MODRM_RM(data[idx]) == Consts.REG_ESI))
                    {
                        dispbytes = 2;
                    }
                }
                else if (Macros.MASK_MODRM_MOD(data[idx]) == 1)
                {
                    dispbytes = 1;
                }
                else if (Macros.MASK_MODRM_MOD(data[idx]) == 2)
                {
                    dispbytes = (pmode == Mode.MODE_32) ? 4U : 2U;
                }



                if (pmode == Mode.MODE_32)
                {
                    if ((Macros.MASK_MODRM_RM(data[idx]) == Consts.REG_ESP) && (Macros.MASK_MODRM_MOD(data[idx]) != 3))
                    {
                        sib             = true;
                        instruction.sib = data[idx + 1];


                        if (instruction.length == 1)
                        {
                            instruction.sib     = data[idx + 1];
                            instruction.length += 1;
                        }
                        basereg  = Macros.MASK_SIB_BASE(data[idx + 1]);
                        indexreg = Macros.MASK_SIB_INDEX(data[idx + 1]);
                        scale    = Macros.MASK_SIB_SCALE(data[idx + 1]) * 2;

                        if (scale == 6)
                        {
                            scale += 2;
                        }


                        if ((basereg == Consts.REG_EBP) && Macros.MASK_MODRM_MOD(data[idx]) == 0)
                        {
                            basereg   = Consts.REG_NOP;
                            dispbytes = 4;
                        }
                        if (indexreg == Consts.REG_ESP)
                        {
                            indexreg = Consts.REG_NOP;
                        }
                    }
                    else
                    {
                        if (Macros.MASK_MODRM_MOD(data[idx]) == 0 && (Macros.MASK_MODRM_RM(data[idx]) == Consts.REG_EBP))
                        {
                            basereg = Consts.REG_NOP;
                        }
                        else
                        {
                            basereg = Macros.MASK_MODRM_RM(data[idx]);
                        }
                    }
                }
                else
                {
                    switch (Macros.MASK_MODRM_RM(data[idx]))
                    {
                    case 0:
                        basereg  = Consts.REG_EBX;
                        indexreg = Consts.REG_ESI;
                        break;

                    case 1:
                        basereg  = Consts.REG_EBX;
                        indexreg = Consts.REG_EDI;
                        break;

                    case 2:
                        basereg  = Consts.REG_EBP;
                        indexreg = Consts.REG_ESI;
                        break;

                    case 3:
                        basereg  = Consts.REG_EBP;
                        indexreg = Consts.REG_EDI;
                        break;

                    case 4:
                        basereg  = Consts.REG_ESI;
                        indexreg = Consts.REG_NOP;
                        break;

                    case 5:
                        basereg  = Consts.REG_EDI;
                        indexreg = Consts.REG_NOP;
                        break;

                    case 6:
                        if (Macros.MASK_MODRM_MOD(data[idx]) == 0)
                        {
                            basereg = Consts.REG_NOP;
                        }
                        else
                        {
                            basereg = Consts.REG_EBP;
                        }
                        indexreg = Consts.REG_NOP;
                        break;

                    case 7:
                        basereg  = Consts.REG_EBX;
                        indexreg = Consts.REG_NOP;
                        break;
                    }
                    if (Macros.MASK_MODRM_MOD(data[idx]) == 3)
                    {
                        basereg  = Macros.MASK_MODRM_RM(data[idx]);
                        indexreg = Consts.REG_NOP;
                    }
                }
            }


            switch (Macros.MASK_AM(oflags))
            {
            case Consts.AM_REG:
                op.type = OperandType.OPERAND_TYPE_REGISTER;
                op.reg  = Macros.MASK_REG(oflags);
                break;


            case Consts.AM_IND:
                op.type    = OperandType.OPERAND_TYPE_MEMORY;
                op.basereg = Macros.MASK_REG(oflags);
                break;


            case Consts.AM_M:
                if (Macros.MASK_MODRM_MOD(data[idx]) == 3)
                {
                    return(false);
                }
                goto skip_rest;

            case Consts.AM_R:
                if (Macros.MASK_MODRM_MOD(data[idx]) != 3)
                {
                    return(false);
                }
                goto skip_rest;

            case Consts.AM_Q:
            case Consts.AM_W:
            case Consts.AM_E:
skip_rest:
                op.type               = OperandType.OPERAND_TYPE_MEMORY;
                op.dispbytes          = dispbytes;
                instruction.dispbytes = dispbytes;
                op.basereg            = basereg;
                op.indexreg           = indexreg;
                op.scale              = scale;

                index = (sib) ? 1U : 0U;
                if (dispbytes != 0)
                {
                    op.dispoffset = index + 1 + idx;
                }
                switch (dispbytes)
                {
                case 0:
                    break;

                case 1:
                    op.displacement = Macros.FETCH8(data, idx + 1 + index);

                    if (op.displacement >= 0x80)
                    {
                        op.displacement |= 0xffffff00;
                    }
                    break;

                case 2:
                    op.displacement = Macros.FETCH16(data, idx + 1 + index);
                    break;

                case 4:
                    op.displacement = Macros.FETCH32(data, idx + 1 + index);
                    break;
                }


                if ((basereg != Consts.REG_NOP) && (Macros.MASK_MODRM_MOD(data[idx]) == 3))
                {
                    op.type = OperandType.OPERAND_TYPE_REGISTER;
                    op.reg  = basereg;
                }
                break;


            case Consts.AM_I1:
                op.type      = OperandType.OPERAND_TYPE_IMMEDIATE;
                op.immbytes  = 1;
                op.immediate = 1;
                break;

            case Consts.AM_J:
                op.type = OperandType.OPERAND_TYPE_IMMEDIATE;

                oflags |= Consts.F_s;
                goto am_i;

            case Consts.AM_I:
am_i:
                op.type      = OperandType.OPERAND_TYPE_IMMEDIATE;
                index        = (inst.modrm) ? 1U : 0U;
                index       += (sib) ? 1U : 0U;
                index       += instruction.immbytes;
                index       += instruction.dispbytes;
                op.immoffset = index + idx;


                mode = MODE_CHECK_OPERAND(mode, iflags);

                switch (Macros.MASK_OT(oflags))
                {
                case Consts.OT_b:
                    op.immbytes  = 1;
                    op.immediate = Macros.FETCH8(data, idx + index);
                    if ((op.immediate >= 0x80) && (Macros.MASK_FLAGS(oflags) == Consts.F_s))
                    {
                        op.immediate |= 0xffffff00;
                    }
                    break;

                case Consts.OT_v:
                    op.immbytes  = (mode == Mode.MODE_32) ? 4U : 2U;
                    op.immediate = (mode == Mode.MODE_32) ? Macros.FETCH32(data, idx + index) : Macros.FETCH16(data, idx + index);
                    break;

                case Consts.OT_w:
                    op.immbytes  = 2;
                    op.immediate = Macros.FETCH16(data, idx + index);
                    break;
                }
                instruction.immbytes += op.immbytes;
                break;


            case Consts.AM_A:
                op.type = OperandType.OPERAND_TYPE_IMMEDIATE;

                mode = MODE_CHECK_OPERAND(mode, iflags);

                op.dispbytes    = (mode == Mode.MODE_32) ? 6U : 4U;
                op.displacement = (mode == Mode.MODE_32) ? Macros.FETCH32(data, idx) : Macros.FETCH16(data, idx);
                op.section      = Macros.FETCH16(data, idx + op.dispbytes - 2);

                instruction.dispbytes    = op.dispbytes;
                instruction.sectionbytes = 2;
                break;


            case Consts.AM_O:
                op.type = OperandType.OPERAND_TYPE_MEMORY;
                switch (Macros.MASK_OT(oflags))
                {
                case Consts.OT_b:
                    op.dispbytes    = 1;
                    op.displacement = Macros.FETCH8(data, idx);
                    break;

                case Consts.OT_v:
                    op.dispbytes    = (mode == Mode.MODE_32) ? 4U : 2U;
                    op.displacement = (mode == Mode.MODE_32) ? Macros.FETCH32(data, idx) : Macros.FETCH16(data, idx);
                    break;
                }
                instruction.dispbytes = op.dispbytes;
                op.dispoffset         = idx;
                break;


            case Consts.AM_G:
                op.type = OperandType.OPERAND_TYPE_REGISTER;
                op.reg  = reg;
                break;


            case Consts.AM_C:

            case Consts.AM_D:

            case Consts.AM_S:

            case Consts.AM_T:

            case Consts.AM_P:

            case Consts.AM_V:
                op.type = OperandType.OPERAND_TYPE_REGISTER;
                op.reg  = Macros.MASK_MODRM_REG(instruction.modrm);
                break;
            }
            return(true);
        }
예제 #7
0
 public static uint get_operand_scale(OPERAND op)
 {
     return(op.scale);
 }
예제 #8
0
 public static uint get_operand_indexreg(OPERAND op)
 {
     return(op.indexreg);
 }
예제 #9
0
 public static uint get_operand_basereg(OPERAND op)
 {
     return(op.basereg);
 }
예제 #10
0
 public static uint get_operand_register(OPERAND op)
 {
     return(op.reg);
 }
예제 #11
0
 public static OperandType get_operand_type(OPERAND op)
 {
     return(op.type);
 }