示例#1
0
        public static UInt32 tq_I(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            instr.ops[op_index].flags |= (byte)OP_TYPE.OPERAND_TYPE_IMM;
            instr.ops[op_index].size = (ushort)opsize.size;
            instr.ops[op_index].value.imm.size = (byte)opsize.size_in_stream;
            instr.ops[op_index].value.imm .offset = (byte)(offset - origin_offset);
            //instr.ops[op_index].value.imm.immab = assembly.Image.ReadBytes(offset, opsize.size_in_stream);

            byte[] bt = assembly.ReadBytes(offset, (int)opsize.size_in_stream);
            instr.ops[op_index].value.imm.imm64 = 0;
            foreach (byte bb in bt.Reverse())
            {
            instr.ops[op_index].value.imm.imm64 <<= 8;
            instr.ops[op_index].value.imm.imm64 += bb;
            }

            //!!!memcpy(&(instr.ops[op_index].value.imm.imm8), offset, opsize.size_in_stream);

            //movsx(ref instr.ops[op_index].value.imm.immab, opsize.size_in_stream, 0x8);
            return (byte)opsize.size_in_stream;
        }
示例#2
0
        static UInt32 post_proc_cmpxchg8b(ulong  origin_offset, ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
        {
            if ((idata.prefixes[PREF_REX_INDEX] != 0xFF) && ((instr.rex & PREFIX_REX_W)!=0))
            {
            idata.is_rex_used = 1;
            instr.mnemonic = "cmpxchg16b";
            instr.ops[0].size = (ushort)OP_SIZE.OPERAND_SIZE_128;
            }

            return 0;
        }
示例#3
0
        static UInt32 post_proc_nop_pause(ulong origin_offset, ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
        {
            if (idata.prefixes[PREF_REP_INDEX] == PREF_REPNZ_ID)
            {
            instr.id = ID_PAUSE;
            instr.groups = GRP_CACHECT | GRP_SSE2;
            idata.prefixes[PREF_REP_INDEX] = 0xFF;
            instr.mnemonic ="pause";
            }

            return 0;
        }
示例#4
0
        static UInt32 parse_operand(ulong origin_offset, ulong offset, INTERNAL_OPERAND iop, INSTRUCTION instr, int op_index, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res = 0;
            OPERAND_SIZE opsize = new OPERAND_SIZE();

            if (iop.type != TQ_NULL)
            {
            instr.ops[op_index].flags |= OPERAND_FLAG_PRESENT;
            if (iop.size >= sq_handlers.Count())
            {
            idata.severe_err = ERRS.ERR_INTERNAL;
            }
            else
            {
            sq_handlers[iop.size](ref opsize, ref instr, idata, mode);
            }

            if (iop.size >= tq_handlers.Count())
            {
            idata.severe_err = ERRS.ERR_INTERNAL;
            }
            else
            {
            res = tq_handlers[iop.type](origin_offset, offset, ref instr, op_index, opsize, idata, mode);
            }
            }

            return res;
        }
示例#5
0
        //Parses operand accordingly to MODRM value.
        static UInt32 parse_rm_operand(ulong origin_offset, ulong  offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, ref INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 len = 0;

            if ((instr.modrm & 0xC0) == 0xC0)
            {
            create_genreg_operand(ref instr, op_index, (byte)(instr.modrm & 0x7), opsize.size, PREFIX_REX_B, ref idata, mode);
            }
            else
            {
            len = parse_mem_operand(origin_offset, offset, ref instr, op_index, opsize, idata, mode);
            }

            return len;
        }
示例#6
0
        //Parses memory address operand.
        static UInt32 parse_mem_operand(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 len;

            instr.ops[op_index].flags |= (byte)OP_TYPE.OPERAND_TYPE_MEM;
            instr.ops[op_index].size = (ushort)opsize.size;
            if (instr.addrsize == ADDR_SIZE_16)
            {
            len = parse_mem_operand_16(origin_offset, offset, ref instr, op_index, mode);
            }
            else
            {
            len = parse_mem_operand_32_64(origin_offset, offset, ref instr, op_index, idata, mode);
            }
            idata.is_addrsize_used = 1;

            return len;
        }
示例#7
0
 //Parses instruction's mnemonic. If mnemonic is simple, it is just copied to
 // struct INSTRUCTION. If mnemonic contains has multi mnemonic indicator (MM_INDICATOR)
 // at first character then it depends on implicit operand's size. In this case the function
 // calls get_instruction_opsize and builds choses mnemonic basing on result.
 static void parse_mnemonic(OPCODE_DESCRIPTOR opcode, INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
 {
     if ((opcode.mnemonic.value.Length>0) && (opcode.mnemonic.value[0] != MM_INDICATOR))
     {
     instr.mnemonic = opcode.mnemonic.value;
     }
     else
     {
     get_instruction_opsize(opcode.mnemonic, instr, idata, mode);
     instr.mnemonic = opcode.mnemonic.values[bsr(instr.opsize) - 1];
     }
 }
示例#8
0
        public static UInt32 tq_T(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            create_reg_operand(ref instr, op_index, REG_TYPE.REG_TYPE_TR, (byte)((instr.modrm >> 0x3) & 0x7), opsize.size);

            return 0x0;
        }
示例#9
0
        public static UInt32 tq_V(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            create_xmmreg_operand(ref instr, op_index, (byte)((instr.modrm >> 0x3) & 0x7), opsize.size, PREFIX_REX_R, ref idata, mode);

            return 0;
        }
示例#10
0
        public static UInt32 tq_rSP(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            create_genreg_operand(ref instr, op_index, REG_CODE_SP, opsize.size, PREFIX_REX_B, ref idata, mode);

            return 0x0;
        }
示例#11
0
        public static UInt32 tq_SS(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            create_reg_operand(ref instr, op_index, REG_TYPE.REG_TYPE_SEG, SREG_CODE_SS, opsize.size);

            return 0;
        }
示例#12
0
 public static UInt32 tq_R(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
 {
     UInt32 res = parse_rm_operand(origin_offset, offset, ref instr, op_index, opsize, ref idata, mode);
     if ((instr.modrm & 0xC0) != 0xC0)
     {
     idata.err = ERRS.ERR_RM_MEM;//error: rm encodes memory.
     }
     return res;
 }
示例#13
0
        public static UInt32 tq_O(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res;

            res = instr.addrsize;
            instr.ops[op_index].flags |= (byte) OP_TYPE.OPERAND_TYPE_MEM;
            instr.ops[op_index].size = (ushort)opsize.size;
            instr.ops[op_index].value.addr.mod = ADDR_MOD_DISP;
            //instr.disp.value.ab = assembly.Image.ReadBytes(offset, instr.addrsize);
            byte[] bt = assembly.ReadBytes(offset, instr.addrsize);
            instr.disp.value.d64 = 0;
            foreach (byte bb in bt.Reverse())
            {
            instr.disp.value.d64 <<= 8;
            instr.disp.value.d64 += bb;
            }

            get_seg(ref instr, op_index, idata.prefixes, mode);

            return res;
        }
示例#14
0
 public static UInt32 tq_J(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
 {
     instr.ops[op_index].flags |= OPERAND_FLAG_REL;
     return tq_I(origin_offset, offset, ref instr, op_index, opsize, idata, mode);
 }
示例#15
0
        //Get instruction's size. Well, really this is size of implicit operand
        // that influences on instruction's mnemonic.
        static void get_instruction_opsize(MULTI_MNEMONIC multi_mnemonic, INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
        {
            OPERAND_SIZE opsize = new OPERAND_SIZE();

            if (multi_mnemonic.size >= sq_handlers.Count())
            {
            idata.severe_err = ERRS.ERR_INTERNAL;
            }
            else
            {
            sq_handlers[multi_mnemonic.size](ref opsize, ref instr, idata, mode);
            }

            instr.opsize = (byte)opsize.size; //Possible sizes are 2/4/8.
        }
示例#16
0
        public static UInt32 tq_W(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res;

            if ((instr.modrm & 0xC0) == 0xC0)
            {
            create_xmmreg_operand(ref instr, op_index, (byte)(instr.modrm & 0x7), opsize.size, PREFIX_REX_B, ref idata, mode);
            res = 0;
            }
            else
            {
            res = parse_mem_operand(origin_offset, offset, ref instr, op_index, opsize, idata, mode);
            }

            return res;
        }
示例#17
0
        //Reads input stream and iterates through tables looking up appropriate struct OPCODE_DESCRIPTOR.
        // Byte value at [offset] is used as index, the function checks tables limits and max instruction's length.
        static UInt32 lookup_opcode(ulong offset, byte table, ref OPCODE_DESCRIPTOR opcode_descr, INTERNAL_DATA idata)
        {
            byte max;
            byte opcode;
            UInt32 res;

            res = 0;
            //opcode_descr = NULL;
            do
            {
            opcode = assembly.ReadBytes(offset, 1)[0];

            opcode >>= tables[table].shift;
            opcode &= tables[table].mask;
            opcode -= tables[table].min;
            //It looks strange, but I want that table descriptors contain
            // "real" values.
            max = (byte)(tables[table].max - tables[table].min);
            if (opcode > max)
            {
            idata.severe_err = ERRS.ERR_BADCODE;
            break;
            }

            if (res > Dasmer.MAX_INSTRUCTION_LEN)
            {
            idata.severe_err = ERRS.ERR_TOO_LONG;
            break;
            }

            if ( (tables[table].props & TBL_PROP_MODRM)==0 )
            {
            res++;
            offset++;
            }

            if ((tables[table].opcodes[opcode].groups & GRP_SWITCH)!=0)
            {
            table = (byte)tables[table].opcodes[opcode].props;// &0xFF;
            continue;
            }
            break;
            }
            while(true);

            if (idata.severe_err == ERRS.ERR_OK)
            opcode_descr = tables[table].opcodes[opcode];

            return res;
        }
示例#18
0
        public static UInt32 tq_X(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res;

            res = 0;
            instr.ops[op_index].flags |= (byte)OP_TYPE.OPERAND_TYPE_MEM;
            instr.ops[op_index].size = (ushort)opsize.size;
            instr.ops[op_index].value.addr.mod = ADDR_MOD_BASE;
            instr.ops[op_index].value.addr.bas = REG_CODE_SI;
            get_seg(ref instr, op_index, idata.prefixes, mode);

            return 0x0;
        }
示例#19
0
        //Parses 32/64bit memory address operand.
        static UInt32 parse_mem_operand_32_64(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 len = 0;

            if ((instr.flags & INSTR_FLAG_SIB)!=0)
            {
            instr.ops[op_index].value.addr.mod = (byte)(instr.modrm >> 0x6);
            instr.ops[op_index].value.addr.bas = (byte)(instr.sib & 0x7);
            instr.ops[op_index].value.addr.index = (byte)((instr.sib >> 3) & 0x7);
            instr.ops[op_index].value.addr.scale = (byte)(1 << (instr.sib >> 0x6));

            if (mode == DISMODE.DISASSEMBLE_MODE_64 && idata.prefixes[PREF_REX_INDEX] != 0xFF)
            {
            if ((instr.rex & PREFIX_REX_B)!=0)
            {
                instr.ops[op_index].value.addr.bas |= REG_CODE_64;
                idata.is_rex_used = 1;
            }
            if ((instr.rex & PREFIX_REX_X)!=0)
            {
                instr.ops[op_index].value.addr.index |= REG_CODE_64;
                idata.is_rex_used = 1;
            }
            }
            len = get_disp(origin_offset, offset, ref instr, op_index, mode);
            get_mod_type_sib(ref instr, op_index);
            }
            else
            {
            instr.ops[op_index].value.addr.mod = (byte)(instr.modrm >> 0x6);
            instr.ops[op_index].value.addr.bas = (byte)(instr.modrm & 0x7);

            if (mode == DISMODE.DISASSEMBLE_MODE_64)
            {
            if ((idata.prefixes[PREF_REX_INDEX] != 0xFF) && ((instr.rex & PREFIX_REX_B)!=0))
            {
                instr.ops[op_index].value.addr.bas |= REG_CODE_64;
                idata.is_rex_used = 1;
            }

            if ( (instr.ops[op_index].value.addr.mod == 0x0) &&
                 ((instr.ops[op_index].value.addr.bas == REG_CODE_BP) ||
                  (instr.ops[op_index].value.addr.bas == REG_CODE_R13)) )
            {
                instr.ops[op_index].value.addr.bas = REG_CODE_IP;
            }
            }
            len = get_disp(origin_offset, offset, ref instr, op_index, mode);
            get_mod_type_modrm(ref instr, op_index);
            }
            get_seg(ref instr, op_index, idata.prefixes, mode);

            return len;
        }
示例#20
0
        public static UInt32 tq_Y(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            instr.ops[op_index].flags |= (byte)OP_TYPE.OPERAND_TYPE_MEM;
            instr.ops[op_index].size = (ushort)opsize.size;
            if (mode == DISMODE.DISASSEMBLE_MODE_64)
            instr.ops[op_index].value.addr.seg = SREG_CODE_CS;
            else
            instr.ops[op_index].value.addr.seg = SREG_CODE_ES;
            instr.ops[op_index].value.addr.mod = ADDR_MOD_BASE;
            instr.ops[op_index].value.addr.bas = REG_CODE_DI;

            return 0x0;
        }
示例#21
0
        //Main function for parsing opcode and prefixes. First of all it parses all prefixes and then
        // looks up for struct OPCODE_DESCRIPTOR. The following algorithm is used to handle instructions that
        // use prefixes as opcode extension:
        //
        // * Have we prefix that may be opcode extension?
        //   No: Lookup starts from 1byte table.
        //       * Is instruction found?
        //         No: Error.
        //         Yes: Success.
        //   Yes: Lookup starts from 'ext_table_index' table.
        //        * Is instruction found?
        //          No: Lookup starts from 1byte table.
        //              * Is instruction found?
        //                No: Error.
        //                Yes: Success.
        //          Yes: Success.
        static UInt32 parse_opcode(ulong offset, ref OPCODE_DESCRIPTOR opcode_descr, ref INSTRUCTION instr, INTERNAL_DATA idata, ref DISASM_INOUT_PARAMS param)
        {
            byte ext_table_index  = 0xFF;
            byte ext_prefix_index = 0;
            UInt32 res;
            UInt32 tmp;

            res = parse_prefixes(offset, ref instr, idata, ext_table_index, ext_prefix_index, ref param);
            if (idata.severe_err==0)
            {
            instr.opcode_offset = (byte)res;
            offset += res;

            if ((ext_table_index != 0xFF) && (offset == 0xF))
            {
            tmp = lookup_opcode(offset, ext_table_index, ref opcode_descr, idata);
            if ((idata.severe_err==0) && (opcode_descr.id != ID_NULL))
            {
                idata.prefixes[ext_prefix_index] = 0xFF;
                check_ext_sf_prefixes(idata.prefixes, ref instr, ref param);
                res += tmp;
            }
            else
            {
                idata.severe_err = 0;
                res += lookup_opcode(offset, IDX_1BYTE, ref opcode_descr, idata);
            }
            }
            else
            {
            res += lookup_opcode(offset, IDX_1BYTE, ref opcode_descr, idata);
            }

            if ((idata.severe_err==0) && (opcode_descr.id == ID_NULL))
            {
            idata.severe_err = ERRS.ERR_BADCODE;//error: invalid opcode.
            }
            }
            return res;
        }
示例#22
0
        public static UInt32 tq_Z(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            byte[] bt = assembly.ReadBytes(offset - 1, 1);
            //We already consumed opcode, hence we need to look backward.
            create_genreg_operand(ref instr, op_index, (byte)(bt[0] & 0x7), opsize.size, PREFIX_REX_B, ref idata, mode);

            return 0x0;
        }
示例#23
0
        //Main function for parsing prefixes. Reads input stream until meets non-prefix byte
        // or maximum instruction length is exceeded. The function checks if a prefix of the same group
        // was already met and if so, replaces old prefix with a new one.
        // Old prefix is added to superfluous prefixes array.
        // The function also checks if a prefix is opcode-extension.
        static UInt32 parse_prefixes(ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, byte ext_table_index, byte ext_pref_index, ref DISASM_INOUT_PARAMS param)
        {
            byte pref_code;
            byte rex_found;
            byte pref_id;
            byte pref_index;
            UInt32 res;
            UInt32 tmp;
            OPCODE_DESCRIPTOR ptr;

            res = 0;
            rex_found = 0;

            while(true)
            {

            //pref_code = *offset;
            pref_code = assembly.ReadBytes(offset, 1)[0];

            if (res > Dasmer.MAX_INSTRUCTION_LEN)
            {
            idata.severe_err = ERRS.ERR_TOO_LONG;//error: instruction too long.
            break;
            }

            ptr = tables[IDX_1BYTE].opcodes[pref_code];
            if ( !( ((ptr.groups & GRP_PREFIX)!=0) ||
                (param.mode == DISMODE.DISASSEMBLE_MODE_64 && (pref_code >= 0x40) && (pref_code <= 0x4F) && (rex_found == 0))))
            {
            break;
            }
            else
            {
            if (rex_found!=0)
            {
                idata.severe_err = ERRS.ERR_REX_NOOPCD;//error: an opcode should follow after rex.
                break;
            }

            if ((rex_found != 0) && (param.mode == DISMODE.DISASSEMBLE_MODE_64))
            {
                if ( (pref_code >= 0x40) && (pref_code <= 0x4F) )
                {
                    idata.prefixes[PREF_REX_INDEX] = PREF_REX_ID;
                    instr.rex = pref_code;
                    rex_found = 1;

                    res++;
                    offset++;
                    continue;
                }
            }

            tmp = tq_handlers[ptr.ops[0].type](0, 0, ref instr, 0, new OPERAND_SIZE(), new INTERNAL_DATA(), param.mode);
            pref_index = (byte)(tmp >> 8);
            pref_id = (byte)tmp;// &0xFF;
            if (idata.prefixes[pref_index] != 0xFF)
            {
                add_sf_prefix(idata.prefixes, pref_index, ref instr, ref param);
            }
            idata.prefixes[pref_index] = pref_id;

            //Used later for prefix table switch.
            if (ptr.id == ID_66 || ptr.id == ID_REPZ || ptr.id == ID_REPNZ)
            {
                ext_table_index =(byte)(ptr.props);
                ext_pref_index = pref_index;
            }

            res++;
            offset++;
            }
            }

            return res;
        }
示例#24
0
        public UInt32 disassemble(ulong offset, ref IInstruction instr1, ref DISASM_INOUT_PARAMS param)
        {
            UInt32 len;
            UInt32 res;
            OPCODE_DESCRIPTOR opcode = new OPCODE_DESCRIPTOR();
            INTERNAL_DATA idata = new INTERNAL_DATA(0xFF);
            INSTRUCTION instr = instr1 as INSTRUCTION;
            //Setup everything.
            //memset(instr, 0x0, sizeof(*instr));
            //memset(&idata, 0x0, sizeof(idata));
            //memset(idata.prefixes, 0xFF, sizeof(idata.prefixes));
            param.sf_prefixes_len = 0;
            param.errcode = 0;
            len = res = 0;
            //Lookup opcode.
            res = parse_opcode(offset, ref opcode, ref instr, idata, ref param);
            if (idata.severe_err != ERRS.ERR_OK)
            {
                param.errcode = idata.severe_err;
                return 0;
            }
            len += res;

            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            get_address_size(ref instr, idata.prefixes, param.mode);

            //Parse MODRM and SIB bytes.
            len += parse_modrm_sib(offset + len, ref instr, opcode);
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            //Copy flags, eflags, id, groups.
            copy_eflags(ref instr, ref opcode);
            copy_instr_flags(ref instr, ref opcode);
            instr.id = opcode.id;
            instr.groups = opcode.groups;

            //Parse mnemonic.
            parse_mnemonic(opcode, instr, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }

            //Deal with operands.
            res = parse_operand(offset, offset + len, opcode.ops[0], instr, 0, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            res = parse_operand(offset, offset + len, opcode.ops[1], instr, 1, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            res = parse_operand(offset, offset + len, opcode.ops[2], instr, 2, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            len += res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
            param.errcode = ERRS.ERR_TOO_LONG;
            return 0;
            }

            //Do postprocessing if necessary.
            if ((opcode.props & PROP_POST_PROC)!=0)
            {
            res = postprocs[opcode.props >> POST_PROC_SHIFT](offset, offset, ref instr, idata, param.mode);
            if (idata.severe_err != ERRS.ERR_OK)
            {
            param.errcode = idata.severe_err;
            return 0;
            }
            if (res>0)
            {
            len = res;
            if (len > Dasmer.MAX_INSTRUCTION_LEN)
            {
                param.errcode = ERRS.ERR_TOO_LONG;
                return 0;
            }
            }
            }

            //Check if REX is superfluous.
            if ((param.mode == DISMODE.DISASSEMBLE_MODE_64) && (idata.is_rex_used != 0))
            add_sf_prefix_value(idata.prefixes, PREF_REX_INDEX, instr.rex, ref instr, ref param);
            //Check if segment prefix is superfluous.
            check_seg_sf_prefixes(instr, idata.prefixes, param);
            //Check if opsize is superfluous.
            if ((idata.is_opsize_used!=0) && idata.prefixes[PREF_OPSIZE_INDEX] != 0xFF)
            add_sf_prefix(idata.prefixes, PREF_OPSIZE_INDEX, ref instr, ref param);
            //Check if addrsize is superfluous.
            if ((idata.is_addrsize_used!=0) && idata.prefixes[PREF_ADDRSIZE_INDEX] != 0xFF)
            add_sf_prefix(idata.prefixes, PREF_ADDRSIZE_INDEX, ref instr, ref param);

            //Convert prefixes to output representation.
            convert_prefixes(instr, idata.prefixes);

            //Copy error if exists.
            param.errcode = idata.err;

            //And post checks.
            if ((param.arch & opcode.arch)!=0)
            param.errcode = ERRS.ERR_ANOT_ARCH;//error: another architecture.
            else if ( ((instr.prefixes & INSTR_PREFIX_LOCK)!=0) && ((opcode.props & PROP_LOCK)==0) )
            param.errcode = ERRS.ERR_NON_LOCKABLE;//error: prefix lock non-lockable instruction.
            else if (((opcode.props & PROP_I64) != 0) && (param.mode == DISMODE.DISASSEMBLE_MODE_64))
            param.errcode = ERRS.ERR_16_32_ONLY;//error: instruction is 16/32bit mode only.
            else if (((opcode.props & PROP_O64) != 0) && (param.mode != DISMODE.DISASSEMBLE_MODE_64))
            param.errcode = ERRS.ERR_64_ONLY;//error: instruction is 64bit mode only.

            apply_disasm_options(ref instr, len, param);
            instr.bytes = assembly.ReadBytes(offset, (int)len);

            instr.Addr = (ulong)offset;
            return len;
        }
示例#25
0
        /*************************
        * Postprocessing routines.
        **************************
        */
        static UInt32 post_proc_arpl_movsxd(ulong origin_offset, ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res;
            res = 0;
            if (mode == DISMODE.DISASSEMBLE_MODE_64)
            {
            OPERAND_SIZE opsize = new OPERAND_SIZE();

            instr.id = ID_MOVSXD;
            instr.groups = GRP_GEN | GRP_CONVER;
            instr.tested_flags = 0;
            instr.modified_flags = 0;
            instr.set_flags = 0;
            instr.cleared_flags = 0;
            instr.flags &= (ushort)(INSTR_FLAG_MODRM | INSTR_FLAG_SIB);

            instr.mnemonic = "movsxd";
            byte[] bt = assembly.ReadBytes((ulong)instr.opcode_offset + 1, 4);
            res = (UInt32)(
              bt[0] +
              bt[1]*256 +
              bt[2]*256*256 +
              bt[3]*256*256*256);
            offset += res;

            if ((instr.flags & INSTR_FLAG_MODRM)!=0)
            {
            res++;
            offset++;
            }
            if ((instr.flags & INSTR_FLAG_SIB)!=0)
            {
            res++;
            offset++;
            }
            instr.ops[0].value.imm.imm64 = 0;
            instr.ops[1].value.imm.imm64 = 0;
            instr.ops[0].flags = OPERAND_FLAG_PRESENT;
            instr.ops[1].flags = OPERAND_FLAG_PRESENT;

            sq_dqp(ref opsize, ref instr, idata, mode);
            res += tq_G(origin_offset, offset, ref instr, 0, opsize, idata, mode);
            sq_d(ref opsize, ref instr, idata, mode);
            res += tq_E(origin_offset, offset, ref instr, 1, opsize, idata, mode);
            }

            return res;
        }
示例#26
0
 static void create_genreg_operand(ref INSTRUCTION instr, int op_index, byte code, OP_SIZE size, byte rex, ref INTERNAL_DATA idata, DISMODE mode)
 {
     if (mode == DISMODE.DISASSEMBLE_MODE_64 && idata.prefixes[PREF_REX_INDEX] != 0xFF)
     {
     if (code > REG_CODE_BX && size == OP_SIZE.OPERAND_SIZE_8)
     {
     code |= REG_CODE_64;
     code += 0x4;
     idata.is_rex_used = 1;
     }
     if ((instr.rex & rex)!=0)
     {
     code |= REG_CODE_64;
     idata.is_rex_used = 1;
     }
     }
     create_reg_operand(ref instr, op_index, REG_TYPE.REG_TYPE_GEN, code, size);
 }
示例#27
0
 static UInt32 post_proc_multinop(ulong origin_offset, ulong offset, ref INSTRUCTION instr, INTERNAL_DATA idata, DISMODE mode)
 {
     instr.ops[0].flags &= (byte)~OPERAND_FLAG_PRESENT;
     instr.ops[1].flags &= (byte)~OPERAND_FLAG_PRESENT;
     instr.ops[2].flags &= (byte)~OPERAND_FLAG_PRESENT;
     return 0;
 }
示例#28
0
 static void create_xmmreg_operand(ref INSTRUCTION instr, int op_index, byte code, OP_SIZE size, byte rex, ref INTERNAL_DATA idata, DISMODE mode)
 {
     if ((mode == DISMODE.DISASSEMBLE_MODE_64) && (idata.prefixes[PREF_REX_INDEX] != 0xFF))
     {
     if ((instr.rex & rex)!=0)
     {
     code |= REG_CODE_64;
     idata.is_rex_used = 1;
     }
     }
     create_reg_operand(ref instr, op_index, REG_TYPE.REG_TYPE_XMM, code, size);
 }
示例#29
0
 static UInt32 tq_1(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
 {
     instr.ops[op_index].flags |= (byte)OP_TYPE.OPERAND_TYPE_IMM;
     instr.ops[op_index].size = (ushort)OP_SIZE.OPERAND_SIZE_8;
     instr.ops[op_index].value.imm.imm8 = 0x1;
     return 0x0;
 }
示例#30
0
        public static UInt32 tq_fES(ulong origin_offset, ulong offset, ref INSTRUCTION instr, int op_index, OPERAND_SIZE opsize, INTERNAL_DATA idata, DISMODE mode)
        {
            UInt32 res;

            if ((instr.modrm & 0xC0) == 0xC0)
            res = tq_fEST(origin_offset, offset, ref instr, op_index, opsize, idata, mode);
            else
            res = tq_M(origin_offset, offset, ref instr, op_index, opsize, idata, mode);

            return res;
        }