MODRM_MOD() public static method

public static MODRM_MOD ( byte b ) : byte
b byte
return byte
Esempio n. 1
0
        decode_vex(ref ud u)
        {
            byte index;

            if (u.dis_mode != 64 && BitOps.MODRM_MOD((byte)inp_peek(ref u)) != 0x3)
            {
                index = 0;
            }
            else
            {
                u.vex_op = (byte)inp_curr(ref u);
                u.vex_b1 = (byte)inp_next(ref u);
                if (u.vex_op == 0xc4)
                {
                    byte pp, m;
                    /* 3-byte vex */
                    u.vex_b2 = inp_next(ref u);
                    if (u.error != 0)
                    {
                        return(u.error);
                    }

                    m = (byte)(u.vex_b1 & 0x1f);
                    if (m == 0 || m > 3)
                    {
                        u.error        = 1;
                        u.errorMessage = "decode-error: reserved vex.m-mmmm value";
                    }
                    pp    = (byte)(u.vex_b2 & 0x3);
                    index = (byte)((pp << 2) | m);
                }
                else
                {
                    /* 2-byte vex */
                    Debug.Assert(u.vex_op == 0xc5);
                    index = (byte)(0x1 | ((u.vex_b1 & 0x3) << 2));
                }
            }
            if (u.le.Table.Length > index)
            {
                return(decode_ext(ref u, u.le.Table[index]));
            }
            else
            {
                u.error        = 1;
                u.errorMessage = string.Format("decoding vex error: index value {0} of 'u.le.Table' is out of range {1}",
                                               index, u.le.Table.Length);
                return(-1);
            }
        }
Esempio n. 2
0
        decode_vex(ref ud u)
        {
            byte index;

            if (u.dis_mode != 64 && BitOps.MODRM_MOD((byte)inp_peek(ref u)) != 0x3)
            {
                index = 0;
            }
            else
            {
                u.vex_op = (byte)inp_curr(ref u);
                u.vex_b1 = (byte)inp_next(ref u);
                if (u.vex_op == 0xc4)
                {
                    byte pp, m;
                    /* 3-byte vex */
                    u.vex_b2 = inp_next(ref u);
                    if (u.error != 0)
                    {
                        return(u.error);
                    }

                    m = (byte)(u.vex_b1 & 0x1f);
                    if (m == 0 || m > 3)
                    {
                        u.error        = 1;
                        u.errorMessage = "decode-error: reserved vex.m-mmmm value";
                        return(u.error);
                    }
                    pp    = (byte)(u.vex_b2 & 0x3);
                    index = (byte)((pp << 2) | m);
                }
                else
                {
                    /* 2-byte vex */
                    Debug.Assert(u.vex_op == 0xc5);
                    index = (byte)(0x1 | ((u.vex_b1 & 0x3) << 2));
                }
            }
            return(decode_ext(ref u, u.le.Table[index]));
        }
Esempio n. 3
0
        decode_operand(ref ud u,
                       ref ud_operand operand,
                       ud_operand_code type,
                       ud_operand_size size)
        {
            operand.type     = ud_type.UD_NONE;
            operand._oprcode = type;

            switch (type)
            {
            case ud_operand_code.OP_A:
                decode_a(ref u, ref operand);
                break;

            case ud_operand_code.OP_MR:
                decode_modrm_rm(ref u, ref operand, (byte)reg_class.REGCLASS_GPR,
                                BitOps.MODRM_MOD(modrm(ref u)) == 3 ?
                                size.Mx_reg_size() : size.Mx_mem_size());
                break;

            case ud_operand_code.OP_F:
                u.br_far = 1;
                if (BitOps.MODRM_MOD(modrm(ref u)) == 3)
                {
                    u.error        = 1;
                    u.errorMessage = "expected modrm.mod != 3\n";
                }
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_GPR, size);
                break;

            case ud_operand_code.OP_M:
                if (BitOps.MODRM_MOD(modrm(ref u)) == 3)
                {
                    u.error        = 1;
                    u.errorMessage = "expected modrm.mod != 3\n";
                }
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_GPR, size);
                break;

            case ud_operand_code.OP_E:
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_GPR, size);
                break;

            case ud_operand_code.OP_G:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_GPR, size);
                break;

            case ud_operand_code.OP_sI:
            case ud_operand_code.OP_I:
                decode_imm(ref u, size, ref operand);
                break;

            case ud_operand_code.OP_I1:
                operand.type        = ud_type.UD_OP_CONST;
                operand.lval.udword = 1;
                break;

            case ud_operand_code.OP_N:
                if (BitOps.MODRM_MOD(modrm(ref u)) != 3)
                {
                    u.error        = 1;
                    u.errorMessage = "expected modrm.mod == 3\n";
                }
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_MMX, size);
                break;

            case ud_operand_code.OP_Q:
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_MMX, size);
                break;

            case ud_operand_code.OP_P:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_MMX, size);
                break;

            case ud_operand_code.OP_U:
                if (BitOps.MODRM_MOD(modrm(ref u)) != 3)
                {
                    u.error        = 1;
                    u.errorMessage = "expected modrm.mod == 3\n";
                }
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_XMM, size);
                break;

            case ud_operand_code.OP_W:
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_XMM, size);
                break;

            case ud_operand_code.OP_V:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_XMM, size);
                break;

            case ud_operand_code.OP_H:
                decode_vex_vvvv(ref u, ref operand, size);
                break;

            case ud_operand_code.OP_MU:
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_XMM,
                                BitOps.MODRM_MOD(modrm(ref u)) == 3 ?
                                size.Mx_reg_size() : size.Mx_mem_size());
                break;

            case ud_operand_code.OP_S:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_SEG, size);
                break;

            case ud_operand_code.OP_O:
                decode_moffset(ref u, size, ref operand);
                break;

            case ud_operand_code.OP_R0:
            case ud_operand_code.OP_R1:
            case ud_operand_code.OP_R2:
            case ud_operand_code.OP_R3:
            case ud_operand_code.OP_R4:
            case ud_operand_code.OP_R5:
            case ud_operand_code.OP_R6:
            case ud_operand_code.OP_R7:
                decode_reg(ref u, ref operand, reg_class.REGCLASS_GPR,
                           (byte)((BitOps.REX_B(u._rex) << 3) | (type - ud_operand_code.OP_R0)), size);
                break;

            case ud_operand_code.OP_AL:
            case ud_operand_code.OP_AX:
            case ud_operand_code.OP_eAX:
            case ud_operand_code.OP_rAX:
                decode_reg(ref u, ref operand, reg_class.REGCLASS_GPR, 0, size);
                break;

            case ud_operand_code.OP_CL:
            case ud_operand_code.OP_CX:
            case ud_operand_code.OP_eCX:
                decode_reg(ref u, ref operand, reg_class.REGCLASS_GPR, 1, size);
                break;

            case ud_operand_code.OP_DL:
            case ud_operand_code.OP_DX:
            case ud_operand_code.OP_eDX:
                decode_reg(ref u, ref operand, reg_class.REGCLASS_GPR, 2, size);
                break;

            case ud_operand_code.OP_ES:
            case ud_operand_code.OP_CS:
            case ud_operand_code.OP_DS:
            case ud_operand_code.OP_SS:
            case ud_operand_code.OP_FS:
            case ud_operand_code.OP_GS:
                /* in 64bits mode, only fs and gs are allowed */
                if (u.dis_mode == 64)
                {
                    if (type != ud_operand_code.OP_FS && type != ud_operand_code.OP_GS)
                    {
                        u.error        = 1;
                        u.errorMessage = "invalid segment register in 64bits\n";
                    }
                }
                operand.type  = ud_type.UD_OP_REG;
                operand.@base = (type - ud_operand_code.OP_ES) + ud_type.UD_R_ES;
                operand.size  = 16;
                break;

            case ud_operand_code.OP_J:
                decode_imm(ref u, size, ref operand);
                operand.type = ud_type.UD_OP_JIMM;
                break;

            case ud_operand_code.OP_R:
                if (BitOps.MODRM_MOD(modrm(ref u)) != 3)
                {
                    u.error        = 1;
                    u.errorMessage = "expected modrm.mod == 3\n";
                }
                decode_modrm_rm(ref u, ref operand, reg_class.REGCLASS_GPR, size);
                break;

            case ud_operand_code.OP_C:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_CR, size);
                break;

            case ud_operand_code.OP_D:
                decode_modrm_reg(ref u, ref operand, reg_class.REGCLASS_DB, size);
                break;

            case ud_operand_code.OP_I3:
                operand.type        = ud_type.UD_OP_CONST;
                operand.lval.@sbyte = 3;
                break;

            case ud_operand_code.OP_ST0:
            case ud_operand_code.OP_ST1:
            case ud_operand_code.OP_ST2:
            case ud_operand_code.OP_ST3:
            case ud_operand_code.OP_ST4:
            case ud_operand_code.OP_ST5:
            case ud_operand_code.OP_ST6:
            case ud_operand_code.OP_ST7:
                operand.type  = ud_type.UD_OP_REG;
                operand.@base = (type - ud_operand_code.OP_ST0) + ud_type.UD_R_ST0;
                operand.size  = 80;
                break;

            case ud_operand_code.OP_L:
                decode_vex_immreg(ref u, ref operand, size);
                break;

            default:
                operand.type = ud_type.UD_NONE;
                break;
            }
            return(operand.type);
        }
Esempio n. 4
0
        decode_modrm_rm(ref ud u,
                        ref ud_operand op,
                        reg_class type,       /* register type */
                        ud_operand_size size) /* operand size */
        {
            int  offset = 0;
            byte mod, rm;

            /* get mod, r/m and reg fields */
            mod = BitOps.MODRM_MOD(modrm(ref u));
            rm  = (byte)((BitOps.REX_B(u._rex) << 3) | BitOps.MODRM_RM(modrm(ref u)));

            /*
             * If mod is 11b, then the modrm.rm specifies a register.
             *
             */
            if (mod == 3)
            {
                decode_reg(ref u, ref op, type, rm, size);
                return;
            }

            /*
             * !11b => Memory Address
             */
            op.type = ud_type.UD_OP_MEM;
            op.size = (byte)resolve_operand_size(ref u, size);

            if (u.adr_mode == 64)
            {
                op.@base = ud_type.UD_R_RAX + rm;
                if (mod == 1)
                {
                    offset = 8;
                }
                else if (mod == 2)
                {
                    offset = 32;
                }
                else if (mod == 0 && (rm & 7) == 5)
                {
                    op.@base = ud_type.UD_R_RIP;
                    offset   = 32;
                }
                else
                {
                    offset = 0;
                }

                /*
                 * Scale-Index-Base (SIB)
                 */
                if ((rm & 7) == 4)
                {
                    inp_next(ref u);

                    op.@base = ud_type.UD_R_RAX + (BitOps.SIB_B(inp_curr(ref u)) | (BitOps.REX_B(u._rex) << 3));
                    op.index = ud_type.UD_R_RAX + (BitOps.SIB_I(inp_curr(ref u)) | (BitOps.REX_X(u._rex) << 3));

                    /* special conditions for base reference */
                    if (op.index == ud_type.UD_R_RSP)
                    {
                        op.index = ud_type.UD_NONE;
                        op.scale = (byte)ud_type.UD_NONE;
                    }
                    else
                    {
                        op.scale = (byte)((1 << BitOps.SIB_S(inp_curr(ref u))) & ~1);
                    }

                    if (op.@base == ud_type.UD_R_RBP || op.@base == ud_type.UD_R_R13)
                    {
                        if (mod == 0)
                        {
                            op.@base = ud_type.UD_NONE;
                        }
                        if (mod == 1)
                        {
                            offset = 8;
                        }
                        else
                        {
                            offset = 32;
                        }
                    }
                }
                else
                {
                    op.scale = 0;
                    op.index = ud_type.UD_NONE;
                }
            }
            else if (u.adr_mode == 32)
            {
                op.@base = ud_type.UD_R_EAX + rm;
                if (mod == 1)
                {
                    offset = 8;
                }
                else if (mod == 2)
                {
                    offset = 32;
                }
                else if (mod == 0 && rm == 5)
                {
                    op.@base = ud_type.UD_NONE;
                    offset   = 32;
                }
                else
                {
                    offset = 0;
                }

                /* Scale-Index-Base (SIB) */
                if ((rm & 7) == 4)
                {
                    inp_next(ref u);

                    op.scale = (byte)((1 << BitOps.SIB_S(inp_curr(ref u))) & ~1);
                    op.index = ud_type.UD_R_EAX + (BitOps.SIB_I(inp_curr(ref u)) | (BitOps.REX_X(u.pfx_rex) << 3));
                    op.@base = ud_type.UD_R_EAX + (BitOps.SIB_B(inp_curr(ref u)) | (BitOps.REX_B(u.pfx_rex) << 3));

                    if (op.index == ud_type.UD_R_ESP)
                    {
                        op.index = ud_type.UD_NONE;
                        op.scale = (byte)ud_type.UD_NONE;
                    }

                    /* special condition for base reference */
                    if (op.@base == ud_type.UD_R_EBP)
                    {
                        if (mod == 0)
                        {
                            op.@base = ud_type.UD_NONE;
                        }
                        if (mod == 1)
                        {
                            offset = 8;
                        }
                        else
                        {
                            offset = 32;
                        }
                    }
                }
                else
                {
                    op.scale = 0;
                    op.index = ud_type.UD_NONE;
                }
            }
            else
            {
                ud_type[] bases = { ud_type.UD_R_BX, ud_type.UD_R_BX, ud_type.UD_R_BP, ud_type.UD_R_BP,
                                    ud_type.UD_R_SI, ud_type.UD_R_DI, ud_type.UD_R_BP, ud_type.UD_R_BX };
                ud_type[] indices = { ud_type.UD_R_SI, ud_type.UD_R_DI, ud_type.UD_R_SI, ud_type.UD_R_DI,
                                      ud_type.UD_NONE, ud_type.UD_NONE, ud_type.UD_NONE, ud_type.UD_NONE };
                op.@base = bases[rm & 7];
                op.index = indices[rm & 7];
                op.scale = 0;
                if (mod == 0 && rm == 6)
                {
                    offset   = 16;
                    op.@base = ud_type.UD_NONE;
                }
                else if (mod == 1)
                {
                    offset = 8;
                }
                else if (mod == 2)
                {
                    offset = 16;
                }
            }

            if (offset > 0)
            {
                decode_mem_disp(ref u, offset, ref op);
            }
            else
            {
                op.offset = 0;
            }
        }
Esempio n. 5
0
        /*
         * decode_ext()
         *
         *    Decode opcode extensions (if any)
         */
        int decode_ext(ref ud u, ushort ptr)
        {
            byte idx = 0;

            if ((ptr & 0x8000) == 0)
            {
                return(decode_insn(ref u, ptr));
            }
            u.le = InstructionTables.ud_lookup_table_list[(~0x8000 & ptr)];
            if (u.le.Type == ud_table_type.UD_TAB__OPC_3DNOW)
            {
                return(decode_3dnow(ref u));
            }

            switch (u.le.Type)
            {
            case ud_table_type.UD_TAB__OPC_MOD:
                /* !11 = 0, 11 = 1 */
                idx = (byte)((BitOps.MODRM_MOD(modrm(ref u)) + 1) / 4);
                break;

            /* disassembly mode/operand size/address size based tables.
             * 16 = 0,, 32 = 1, 64 = 2
             */
            case ud_table_type.UD_TAB__OPC_MODE:
                idx = (byte)(u.dis_mode != 64 ? 0 : 1);
                break;

            case ud_table_type.UD_TAB__OPC_OSIZE:
                idx = (byte)(eff_opr_mode(u.dis_mode, BitOps.REX_W(u.pfx_rex), u.pfx_opr) / 32);
                break;

            case ud_table_type.UD_TAB__OPC_ASIZE:
                idx = (byte)(eff_adr_mode(u.dis_mode, u.pfx_adr) / 32);
                break;

            case ud_table_type.UD_TAB__OPC_X87:
                idx = (byte)(modrm(ref u) - 0xC0);
                break;

            case ud_table_type.UD_TAB__OPC_VENDOR:
                if (u.vendor == UD_VENDOR_ANY)
                {
                    /* choose a valid entry */
                    idx = (byte)((u.le.Table[idx] != 0) ? 0 : 1);
                }
                else if (u.vendor == UD_VENDOR_AMD)
                {
                    idx = 0;
                }
                else
                {
                    idx = 1;
                }
                break;

            case ud_table_type.UD_TAB__OPC_RM:
                idx = BitOps.MODRM_RM(modrm(ref u));
                break;

            case ud_table_type.UD_TAB__OPC_REG:
                idx = BitOps.MODRM_REG(modrm(ref u));
                break;

            case ud_table_type.UD_TAB__OPC_SSE:
                return(decode_ssepfx(ref u));

            case ud_table_type.UD_TAB__OPC_VEX:
                return(decode_vex(ref u));

            case ud_table_type.UD_TAB__OPC_VEX_W:
                idx = vex_w(ref u);
                break;

            case ud_table_type.UD_TAB__OPC_VEX_L:
                idx = vex_l(ref u);
                break;

            case ud_table_type.UD_TAB__OPC_TABLE:
                inp_next(ref u);
                return(decode_opcode(ref u));

            default:
                Debug.Assert(false, "not reached");
                break;
            }

            return(decode_ext(ref u, u.le.Table[idx]));
        }