Represents an x86 instruction.
Exemple #1
0
        /// <summary>
        /// Writes an instruction to the output stream.
        /// </summary>
        /// <param name="instruction">The instruction to write.</param>
        public void Write(X86Instruction instruction)
        {
            var opcode = instruction.OpCode;
            WriteOpCode(opcode);

            var mnemonicIndex = Array.IndexOf(opcode.Mnemonics, instruction.Mnemonic);
            if (mnemonicIndex == -1)
                throw new ArgumentException("Instruction's mnemonic is not supported by its opcode.");

            if (opcode.HasRegisterToken)
            {
                var token = (byte)(ComputeRegisterTokenPart(opcode.OperandTypes1[mnemonicIndex],
                                        opcode.OperandSizes1[mnemonicIndex], instruction.Operand1) |
                                   ComputeRegisterTokenPart(opcode.OperandTypes2[mnemonicIndex],
                                       opcode.OperandSizes2[mnemonicIndex], instruction.Operand2));

                if (opcode.HasOpCodeModifier)
                {
                    token |= (byte)(mnemonicIndex << 3);
                }

                _writer.WriteByte(token);
            }

            if (instruction.Operand1 != null)
            {
                WriteOperand(opcode.OperandTypes1[mnemonicIndex],
                    opcode.OperandSizes1[mnemonicIndex], instruction.Operand1);
                if (instruction.Operand2 != null)
                {
                    WriteOperand(opcode.OperandTypes2[mnemonicIndex],
                        opcode.OperandSizes2[mnemonicIndex], instruction.Operand2);
                }
            }
        }
        /// <summary>
        /// Disassembles the next instruction of the input stream.
        /// </summary>
        /// <returns>The disassembled instruction.</returns>
        public X86Instruction ReadNextInstruction()
        {
            long offset = BaseAddress + _reader.Position;
            byte code1 = _reader.ReadByte();
            var instruction = new X86Instruction(offset)
            {
                OpCode = ReadOpcode(code1)
            };

            if (instruction.OpCode.Mnemonics == null)
            {
                instruction.Operand1 = new X86Operand(code1);
                return instruction;
            }

            var registerToken = instruction.OpCode.HasRegisterToken ? _reader.ReadByte() : (byte)0;
            var mnemonicIndex = instruction.OpCode.HasOpCodeModifier ? (registerToken >> 3) & 7 : 0;
            instruction.Mnemonic = instruction.OpCode.Mnemonics[mnemonicIndex];

            instruction.Operand1 = ReadOperand(instruction.OpCode.OperandTypes1[mnemonicIndex],
                instruction.OpCode.OperandSizes1[mnemonicIndex], instruction.OpCode.Op1, registerToken);

            instruction.Operand2 = ReadOperand(instruction.OpCode.OperandTypes2[mnemonicIndex],
                instruction.OpCode.OperandSizes2[mnemonicIndex], instruction.OpCode.Op1, registerToken);

            return instruction;
        }
        private static IEnumerable<X86Instruction> CreateOpCodeRegisterTokenTestInstructions()
        {
            var opcode = X86OpCodes.Arithmetic_RegOrMem8_Imm8;
            for (int index = 0; index < opcode.Mnemonics.Length; index++)
            {
                var mnemonic = opcode.Mnemonics[index];

                var instruction = new X86Instruction()
                {
                    OpCode = opcode,
                    Mnemonic = mnemonic,
                    Operand1 = new X86Operand(X86OperandUsage.BytePointer, 0x1337u),
                    Operand2 = new X86Operand((byte)index),
                };

                yield return instruction;
            }
        }
        private static IEnumerable<X86Instruction> CreateRegOrMemSibTestInstructions(X86OpCode opcode, X86Mnemonic mnemonic)
        {
            for (int operandType = 0; operandType < 3; operandType++)
            {
                for (int multiplier = 1; multiplier < 16; multiplier*=2)
                {
                    for (int scaledRegIndex = 0; scaledRegIndex < 8; scaledRegIndex++)
                    {
                        if (scaledRegIndex == 4)
                            continue;

                        var operand1 = new X86Operand(X86OperandUsage.BytePointer, X86Register.Eax,
                            new X86ScaledIndex((X86Register)scaledRegIndex | X86Register.Eax, multiplier));

                        var operand2 = new X86Operand(X86OperandUsage.Normal, X86Register.Al);

                        var instruction = new X86Instruction()
                        {
                            OpCode = opcode,
                            Mnemonic = mnemonic,
                            Operand1 = operand1,
                            Operand2 = operand2,
                        };

                        switch (operandType)
                        {
                            case 1:
                                operand1.Offset = 1;
                                operand1.OffsetType = X86OffsetType.Short;
                                break;
                            case 2:
                                operand1.Offset = 0x1337;
                                operand1.OffsetType = X86OffsetType.Long;
                                break;
                        }

                        yield return instruction;
                    }
                }
            }
        }
        private static IEnumerable<X86Instruction> CreateRegOrMemTestInstructions(X86OpCode opcode, X86Mnemonic mnemonic, bool flippedOperands)
        {
            for (int operandType = 0; operandType < 3; operandType++)
            {
                for (int register2Index = 0; register2Index < 8; register2Index++)
                {
                    for (int register1Index = 0; register1Index < 8; register1Index++)
                    {
                        var operand1 = new X86Operand(X86OperandUsage.BytePointer,
                            (X86Register)register1Index | X86Register.Eax);
                        var operand2 = new X86Operand(X86OperandUsage.Normal, (X86Register)register2Index);

                        var instruction = new X86Instruction()
                        {
                            OpCode = opcode,
                            Mnemonic = mnemonic,
                        };

                        if (flippedOperands)
                        {
                            instruction.Operand2 = operand1;
                            instruction.Operand1 = operand2;
                        }
                        else
                        {
                            instruction.Operand1 = operand1;
                            instruction.Operand2 = operand2;
                        }

                        switch (register1Index)
                        {
                            case 4: // esp
                                continue;
                            case 5: // ebp
                                if (operandType != 0)
                                    continue;
                                operand1.Value = 0x1337u;
                                break;
                        }

                        switch (operandType)
                        {
                            case 1:
                                operand1.Offset = 1;
                                operand1.OffsetType = X86OffsetType.Short;
                                break;
                            case 2:
                                operand1.Offset = 0x1337;
                                operand1.OffsetType = X86OffsetType.Long;
                                break;
                        }
                        yield return instruction;
                    }
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Formats an instruction to a readable string.
        /// </summary>
        /// <param name="formatter">The formatter to use.</param>
        /// <param name="instruction">The isntruction to format.</param>
        /// <returns>The formatted operand.</returns>
        public static string FormatInstruction(this IX86Formatter formatter, X86Instruction instruction)
        {
            var mnemonicString = formatter.FormatMnemonic(instruction.Mnemonic);

            if (instruction.Operand2 == null)
            {
                return instruction.Operand1 == null
                    ? mnemonicString
                    : mnemonicString + ' ' + formatter.FormatOperand(instruction.Operand1);
            }

            return mnemonicString + ' ' + formatter.FormatOperand(instruction.Operand1) + ", " +
                   formatter.FormatOperand(instruction.Operand2);
        }
 public X86InstructionListViewItem(X86Instruction instruction, byte[] bytes)
 {
     Instruction = instruction;
     Bytes = bytes;
 }