Represents a 32-bit assembly instruction.
Ejemplo n.º 1
0
        private void ProcessOverrideOperand(ref x86Instruction instruction)
        {
            x86OperandType operandType = instruction.OpCode.GetOverrideOperandType();

            if (operandType.HasFlag(x86OperandType.ForceDwordPointer))
            {
                if (instruction.operand2 != null)
                {
                    if (instruction.operand2.Value is uint)
                    {
                        instruction.operand2 = CreatePtr((uint)instruction.operand2.Value, OperandType.DwordPointer);
                    }
                    else
                    {
                        instruction.operand2.ValueType = OperandType.DwordPointer;
                    }
                }
                else
                if (instruction.operand1.Value is uint)
                {
                    instruction.operand1 = CreatePtr((uint)instruction.operand1.Value, OperandType.DwordPointer);
                }
                else
                {
                    instruction.operand1.ValueType = OperandType.DwordPointer;
                }
            }
            if (operandType.HasFlag(x86OperandType.OverrideOperandOrder))
            {
                Operand temp = instruction.operand1;
                instruction.operand1 = instruction.operand2;
                instruction.operand2 = temp;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Replaces an instruction with a new instruction.
        /// </summary>
        /// <param name="targetInstruction">The instruction to replace.</param>
        /// <param name="newInstruction">The new instruction.</param>
        /// <param name="overwriteWhenLarger">A boolean indicating whenever the new instruction is larger, it should overwrite the following instructions.</param>
        public void Replace(x86Instruction targetInstruction, x86Instruction newInstruction, bool overwriteWhenLarger)
        {
            int targetOffset = (int)targetInstruction.Offset.FileOffset;

            if (!overwriteWhenLarger && targetInstruction.Size < newInstruction.Size)
            {
                throw new ArgumentException("The size of the new instruction is bigger than the target instruction.", "newInstruction");
            }

            newInstruction.Offset = targetInstruction.Offset;

            int NopsToAdd = CalculateSpaceNeeded(targetInstruction, newInstruction) - newInstruction.Size;

            byte[] NOPS = new byte[NopsToAdd];

            for (int i = 0; i < NopsToAdd; i++)
            {
                NOPS[i] = 0x90;
            }

            image.SetOffset(targetOffset);
            image.Writer.Write(newInstruction.OpCode.opcodebytes);
            if (newInstruction.operandbytes != null)
            {
                image.Writer.Write(newInstruction.operandbytes);
            }
            image.Writer.Write(NOPS);
        }
Ejemplo n.º 3
0
        private void ProcessInvalidInstruction(ref x86Instruction instruction)
        {
            byte firstByte = instruction.OpCode.OpCodeBytes[0];

            instruction.OpCode             = x86OpCode.Create(x86OpCodes.Unknown);
            instruction.OpCode.opcodebytes = new byte[] { firstByte };
            CurrentOffset = instruction.Offset.FileOffset + 1;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates an instance of a x86 instruction with two operands.
        /// </summary>
        /// <param name="assembly">The parent assembly.</param>
        /// <param name="opcode">The opcode to use.</param>
        /// <param name="operand1">The first operand to use.</param>
        /// <param name="operand2">The second operand to use.</param>
        /// <returns></returns>
        public static x86Instruction Create(x86OpCode opcode, Operand operand1, Operand operand2)
        {
            x86Instruction newInstruction = new x86Instruction();

            newInstruction.OpCode   = opcode;
            newInstruction.operand1 = operand1;
            newInstruction.operand2 = operand2;
            newInstruction.GenerateBytes();
            return(newInstruction);
        }
Ejemplo n.º 5
0
        private void DecodeDoubleRegisters(ref x86Instruction instruction, byte registersToken)
        {
            x86Instruction result       = instruction;
            x86OpCode      resultopcode = instruction.OpCode;

            if (resultopcode.variableByteIndex == -1)
            {
                return;
            }
            resultopcode.opcodebytes[instruction.OpCode.variableByteIndex] = registersToken;
            result.OpCode = resultopcode;

            // lea instructions has got different notations.
            bool isLEA = instruction.OpCode.IsBasedOn(x86OpCodes.Lea);

            x86Register register1;
            x86Register register2;

            DecodeRegisterPair(instruction, registersToken, out register1, out register2);

            // one register is a dword pointer
            if (registersToken <= 0x3F)
            {
                instruction.operand1 = new Operand(register1, OperandType.DwordPointer);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // one register is a dword pointer with an sbyte addition
            else if (registersToken > 0x3F && registersToken < 0x7F)
            {
                instruction.operandbytes = reader.ReadBytes(1);
                instruction.code.operandlength++;
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, ASMGlobals.ByteToSByte(instruction.operandbytes[0]));
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // one register is a dword pointer with an int32 addition
            else if (registersToken >= 0x80 && registersToken <= 0xBF)
            {
                instruction.operandbytes        = reader.ReadBytes(4);
                instruction.code.operandlength += 4;
                int addition = BitConverter.ToInt32(instruction.operandbytes, 0);
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, addition);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // normal multiple registers.
            else if (registersToken >= 0xC0 && registersToken <= 0xFF)
            {
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.Normal);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
        }
        /// <summary>
        /// Gets the assembly instruction in the application by its virtual offset.
        /// </summary>
        /// <param name="TargetOffset">The Offset of the instruction go get.</param>
        /// <returns></returns>
        public x86Instruction GetInstructionByVirtualOffset(ulong TargetOffset)
        {
            x86Instruction TargetInstruction = null;

            foreach (x86Instruction instr in List)
            {
                if (instr.Offset.Va == TargetOffset)
                {
                    TargetInstruction = instr;
                    break;
                }
            }

            return(TargetInstruction);
        }
        /// <summary>
        /// Gets the assembly instruction in the application by its offset.
        /// </summary>
        /// <param name="TargetOffset">The Offset of the instruction go get.</param>
        /// <returns></returns>
        public x86Instruction GetInstructionByOffset(long TargetOffset)
        {
            x86Instruction TargetInstruction = null;

            foreach (x86Instruction instr in List)
            {
                if (instr.Offset.FileOffset == TargetOffset)
                {
                    TargetInstruction = instr;
                    break;
                }
            }

            return(TargetInstruction);
            //int TargetInstructionIndex = assembly.instructions.IndexOf(TargetInstruction);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Calculates and returns the size in bytes needed when replacing an instruction
        /// </summary>
        /// <param name="targetInstruction">The instruction to be replaced.</param>
        /// <param name="newSize">The new instruction's size.</param>
        /// <returns></returns>
        public int CalculateSpaceNeeded(x86Instruction targetInstruction, int newSize)
        {
            if (newSize <= targetInstruction.Size)
                return targetInstruction.Size;

            int sizeNeeded = 0;

            uint currentOffset = targetInstruction.Offset.FileOffset;
            while (sizeNeeded < newSize)
            {
                disassembler.CurrentOffset = currentOffset;
                x86Instruction currentInstruction = disassembler.DisassembleNextInstruction();
                sizeNeeded += currentInstruction.Size;
                currentOffset += (uint)currentInstruction.Size;
            }
            return sizeNeeded;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Disassembles the next instruction at the current offset.
        /// </summary>
        /// <returns></returns>
        public x86Instruction DisassembleNextInstruction()
        {
            x86Instruction newInstruction = new x86Instruction();

            newInstruction.Offset = Offset.FromFileOffset((uint)reader.BaseStream.Position, assembly);

            newInstruction.OpCode = RetrieveNextOpCode();
            ProcessVariableByteIndex(ref newInstruction.code);

            ProcessRegisterOperands(ref newInstruction);
            byte[] rawOperand = ReadRawOperand(newInstruction.OpCode);
            newInstruction.operandbytes = ASMGlobals.MergeBytes(newInstruction.operandbytes, rawOperand);
            ProcessOperandBytes(ref newInstruction);

            ProcessOverrideOperand(ref newInstruction);

            return(newInstruction);
        }
Ejemplo n.º 10
0
        private void ProcessRegisterOperands(ref x86Instruction instruction)
        {
            switch (instruction.OpCode.GetRegisterOperandType())
            {
            case x86OperandType.Multiple32Register:
            case x86OperandType.Multiple32Or8Register:
            case x86OperandType.Multiple16Register:
            case x86OperandType.RegisterLeaRegister:
                DecodeDoubleRegisters(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                break;

            case x86OperandType.Register8:
            case x86OperandType.Register32:
            case x86OperandType.Register32Or8:
                DecodeSingleRegister(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                break;
            }
        }
        /// <summary>
        /// Gets the assembly instruction in the application by its virtual offset.
        /// </summary>
        /// <param name="TargetOffset">The Offset of the instruction go get.</param>
        /// <returns></returns>
        public int GetInstructionIndexByVirtualOffset(ulong TargetOffset)
        {
            x86Instruction TargetInstruction = null;

            foreach (x86Instruction instr in List)
            {
                if (instr.Offset.Va == TargetOffset)
                {
                    TargetInstruction = instr;
                    break;
                }
            }
            if (TargetInstruction == null)
            {
                return(-1);
            }

            return(List.IndexOf(TargetInstruction));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Disassembles bytes to a collection of assembly instructions.
        /// </summary>
        /// <param name="rawStartOffset">The starting offset</param>
        /// <param name="length">The length. This value is overwritten when the last instruction's bounds are outside of the bounds.</param>
        /// <returns></returns>
        public InstructionCollection Disassemble(long rawStartOffset, long length)
        {
            reader.BaseStream.Position = rawStartOffset;
            InstructionCollection instructions = new InstructionCollection();

            long offset    = rawStartOffset;
            long endOffset = rawStartOffset + length;

            while (reader.BaseStream.Position < endOffset)
            {
                x86Instruction instruction = DisassembleNextInstruction();
                instructions.Add(instruction);
                offset += instruction.Size;
                reader.BaseStream.Position = offset;
            }

            //  reader.Dispose();
            return(instructions);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Calculates and returns the size in bytes needed when replacing an instruction
        /// </summary>
        /// <param name="targetInstruction">The instruction to be replaced.</param>
        /// <param name="newSize">The new instruction's size.</param>
        /// <returns></returns>
        public int CalculateSpaceNeeded(x86Instruction targetInstruction, int newSize)
        {
            if (newSize <= targetInstruction.Size)
            {
                return(targetInstruction.Size);
            }

            int sizeNeeded = 0;

            uint currentOffset = targetInstruction.Offset.FileOffset;

            while (sizeNeeded < newSize)
            {
                disassembler.CurrentOffset = currentOffset;
                x86Instruction currentInstruction = disassembler.DisassembleNextInstruction();
                sizeNeeded    += currentInstruction.Size;
                currentOffset += (uint)currentInstruction.Size;
            }
            return(sizeNeeded);
        }
Ejemplo n.º 14
0
        private void DecodeRegisterPair(x86Instruction instruction, byte registerToken, out x86Register register1, out x86Register register2)
        {
            byte registerToken1 = (byte)(registerToken >> 4 << 4);        // high bits.
            byte registerToken2 = (byte)(registerToken - registerToken1); // lower bits.

            while (registerToken1 >= 0x40)
            {
                registerToken1 -= 0x40;
            }
            registerToken1 /= 8;
            if (registerToken2 > 0x7)
            {
                registerToken2 -= 8;
                registerToken1++;
            }

            switch (instruction.OpCode.OperandType)
            {
            case x86OperandType.Multiple16Register:
                // add bit16 mask
                registerToken1 |= (byte)x86Register.Bit16Mask;
                registerToken2 |= (byte)x86Register.Bit16Mask;
                break;

            case x86OperandType.Multiple32Or8Register:
                // Not sure if right or not
                byte mask1;
                byte mask2;
                GetRegisterMask(registerToken, out mask1, out mask2);
                registerToken1 |= mask1;
                registerToken2 |= mask2;
                break;

            case x86OperandType.Multiple32Register:
                // do nothing, normal registers are used.
                break;
            }
            // notice inverted registers.
            register2 = (x86Register)registerToken1;
            register1 = (x86Register)registerToken2;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Replaces an instruction with a new instruction.
        /// </summary>
        /// <param name="targetInstruction">The instruction to replace.</param>
        /// <param name="newInstruction">The new instruction.</param>
        /// <param name="overwriteWhenLarger">A boolean indicating whenever the new instruction is larger, it should overwrite the following instructions.</param>
        public void Replace(x86Instruction targetInstruction, x86Instruction newInstruction, bool overwriteWhenLarger)
        {
            int targetOffset = (int)targetInstruction.Offset.FileOffset;
            if (!overwriteWhenLarger && targetInstruction.Size < newInstruction.Size)
                throw new ArgumentException("The size of the new instruction is bigger than the target instruction.", "newInstruction");

            newInstruction.assembly = image.assembly;
            newInstruction.Offset = targetInstruction.Offset;

            int NopsToAdd = CalculateSpaceNeeded(targetInstruction, newInstruction) - newInstruction.Size;
            byte[] NOPS = new byte[NopsToAdd];

            for (int i = 0; i < NopsToAdd; i++)
                NOPS[i] = 0x90;

            image.Write(targetOffset, newInstruction.OpCode.opcodebytes);
            if (newInstruction.operandbytes != null)
                image.Write(targetOffset + newInstruction.OpCode.opcodebytes.Length, newInstruction.operandbytes);
            image.Write(targetOffset + newInstruction.Size, NOPS);
        }
Ejemplo n.º 16
0
        private ListViewItem CreateListViewItem(x86Instruction instr)
        {
            ListViewItem itm = new ListViewItem();
            itm.UseItemStyleForSubItems = false;
            if (virtualInstructions)
                itm.Text = instr.Offset.Va.ToString("X8");
            else
                itm.Text = instr.Offset.FileOffset.ToString("X8");

            itm.SubItems.Add(ByteArrayToHexString(instr.OpCode.OpCodeBytes) + " " + ByteArrayToHexString(instr.OperandBytes));
            itm.SubItems.Add(instr.ToAsmString(virtualInstructions));
            itm.SubItems.Add("");

            if (instr.OpCode.OperandType == x86OperandType.InstructionAddress || instr.OpCode.OperandType == x86OperandType.ShortInstructionAddress || instr.OpCode.OperandType == x86OperandType.DwordPtr)
            {
                if (instr.OpCode.Name.StartsWith("CALL"))
                    itm.SubItems[2].BackColor = Color.Cyan;
                if (instr.OpCode.Name.StartsWith("J") || instr.OpCode.Name.StartsWith("LOOP"))
                    itm.SubItems[2].BackColor = Color.Yellow;
            }

            itm.Tag = instr;
            return itm;
        }
 /// <summary>
 /// Gets the index of a given instruction.
 /// </summary>
 /// <param name="instruction">The instruction to get the index from.</param>
 /// <returns></returns>
 public int IndexOf(x86Instruction instruction)
 {
     return(List.IndexOf(instruction));
 }
Ejemplo n.º 18
0
        internal void ProcessOperandBytes(x86Instruction instruction)
        {
            uint nextOffset = (uint)(instruction.Offset.FileOffset + instruction.Size);

            Operand operandValue = null;
            switch (instruction.OpCode.GetNormalOperandType())
            {
                case x86OperandType.Byte:
                    operandValue = new Operand(instruction.operandbytes[0]);
                    break;
                case x86OperandType.Word:
                    operandValue = new Operand(BitConverter.ToInt16(instruction.operandbytes, 0));
                    break;
                case x86OperandType.WordAndByte:
                    break; // TODO
                case x86OperandType.Dword:
                    operandValue = new Operand(BitConverter.ToUInt32(instruction.operandbytes, 0));
                    break;
                case x86OperandType.Fword:
                    break; // TODO
                case x86OperandType.Qword:
                    operandValue = new Operand(BitConverter.ToUInt64(instruction.operandbytes, 0));
                    break;
                case x86OperandType.InstructionAddress:
                    operandValue = CreateTargetOffset((uint)(nextOffset + BitConverter.ToInt32(instruction.operandbytes, 0)));
                    break;
                case x86OperandType.ShortInstructionAddress:
                    operandValue = CreateTargetOffset((uint)(nextOffset + ASMGlobals.ByteToSByte(instruction.operandbytes[0])));
                    break;
                case x86OperandType.Register32:
                    DecodeSingleRegister(ref instruction, instruction.code._opcodeBytes[instruction.code._opcodeBytes.Length - 1]);
                    break;
                case x86OperandType.Instruction:
                    // opcode is prefix.
                    x86Instruction nextInstruction = DisassembleNextInstruction();
                    operandValue = new Operand(nextInstruction);
                    instruction.operandbytes = ASMGlobals.MergeBytes(nextInstruction.code.OpCodeBytes, nextInstruction.operandbytes);
                    instruction.code._operandLength = nextInstruction.Size;
                    break;
                case x86OperandType.None:
                    if (instruction.code.IsBasedOn(x86OpCodes.Unknown))
                        operandValue = new Operand(instruction.code._opcodeBytes[0]);
                    break;
            }

            if (operandValue != null)
            {
                if (instruction.operand1 != null)
                    instruction.operand2 = operandValue;
                else
                    instruction.operand1 = operandValue;
            }
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Inserts at the specified index an instruction into the collection.
 /// </summary>
 /// <param name="index">The zero-based index at which value should be inserted.</param>
 /// <param name="instruction">The instruction to insert into the collection.</param>
 public void Insert(int index, x86Instruction instruction)
 {
     List.Insert(index, instruction);
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Gets the index of a given instruction.
 /// </summary>
 /// <param name="instruction">The instruction to get the index from.</param>
 /// <returns></returns>
 public int IndexOf(x86Instruction instruction)
 {
     return List.IndexOf(instruction);
 }
Ejemplo n.º 21
0
        /// <summary>
        /// Disassembles the next instruction at the current offset.
        /// </summary>
        /// <returns></returns>
        public virtual x86Instruction DisassembleNextInstruction()
        {
            x86Instruction newInstruction = new x86Instruction();
            newInstruction.Offset = Offset.FromFileOffset((uint)reader.BaseStream.Position, assembly) ;

            newInstruction.OpCode = RetrieveNextOpCode();
            ProcessVariableByteIndex(ref newInstruction.code);

            ProcessRegisterOperands(newInstruction);
            byte[] rawOperand = ReadRawOperand(newInstruction.OpCode);
            newInstruction.operandbytes = ASMGlobals.MergeBytes(newInstruction.operandbytes, rawOperand);
            ProcessOperandBytes(newInstruction);

            ProcessOverrideOperand(newInstruction);

            return newInstruction;
        }
Ejemplo n.º 22
0
 /// <summary>
 /// Creates a new instance of the ReadingProcessChangedEventArgs containing information about the new instruction and offset.
 /// </summary>
 /// <param name="totallength">The total lenght of the bytes.</param>
 /// <param name="currentoffset">The current offset of the bytes.</param>
 /// <param name="NewInstruction">The new instruction that is read from the bytes.</param>
 public ReadingProcessChangedEventArgs(long totallength, int currentoffset, x86Instruction NewInstruction)
 {
     filelength  = totallength ;
     current = currentoffset;
     newinstruction = NewInstruction;
 }
Ejemplo n.º 23
0
        internal void DecodeRegisterPair(x86Instruction instruction, byte registerToken, out x86Register register1, out x86Register register2)
        {
            byte registerToken1 = (byte)(registerToken >> 4 << 4); // high bits.
            byte registerToken2 = (byte)(registerToken - registerToken1); // lower bits.

            while (registerToken1 >= 0x40)
                registerToken1 -= 0x40;
            registerToken1 /= 8;
            if (registerToken2 > 0x7)
            {
                registerToken2 -= 8;
                registerToken1++;
            }

            switch (instruction.OpCode.OperandType)
            {
                case x86OperandType.Multiple16Register:
                    // add bit16 mask
                    registerToken1 |= (byte)x86Register.Bit16Mask;
                    registerToken2 |= (byte)x86Register.Bit16Mask;
                    break;
                case x86OperandType.Multiple32Or8Register:
                    // Not sure if right or not
                    byte mask1;
                    byte mask2;
                    GetDoubleRegisterMask(registerToken, out mask1, out mask2);
                    registerToken1 |= mask1;
                    registerToken2 |= mask2;
                    break;
                case x86OperandType.Multiple32Register:
                    // do nothing, normal registers are used.
                    break;

            }
            // notice inverted registers.
            register2 = (x86Register)registerToken1;
            register1 = (x86Register)registerToken2;
        }
 /// <summary>
 /// Inserts at the specified index an instruction into the collection.
 /// </summary>
 /// <param name="index">The zero-based index at which value should be inserted.</param>
 /// <param name="instruction">The instruction to insert into the collection.</param>
 public void Insert(int index, x86Instruction instruction)
 {
     List.Insert(index, instruction);
 }
Ejemplo n.º 25
0
        private void DecodeDoubleRegisters(ref x86Instruction instruction, byte registersToken)
        {
            x86Instruction result = instruction;
            x86OpCode resultopcode = instruction.OpCode;
            if (resultopcode._variableByteIndex == -1)
                return;
            resultopcode._opcodeBytes[instruction.OpCode._variableByteIndex] = registersToken;
            result.OpCode = resultopcode;

            // lea instructions has got different notations.
            bool isLEA = instruction.OpCode.IsBasedOn(x86OpCodes.Lea);

            x86Register register1;
            x86Register register2;

            DecodeRegisterPair(instruction, registersToken, out register1, out register2);

            // one register is a dword pointer
            if (registersToken <= 0x3F)
            {
                instruction.operand1 = new Operand(register1, OperandType.DwordPointer);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // one register is a dword pointer with an sbyte addition
            else if (registersToken > 0x3F && registersToken < 0x7F)
            {
                instruction.operandbytes = reader.ReadBytes(1);
                instruction.code._operandLength++;
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, ASMGlobals.ByteToSByte(instruction.operandbytes[0]));
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // one register is a dword pointer with an int32 addition
            else if (registersToken >= 0x80 && registersToken <= 0xBF)
            {
                instruction.operandbytes = reader.ReadBytes(4);
                instruction.code._operandLength += 4;
                int addition = BitConverter.ToInt32(instruction.operandbytes, 0);
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.DwordPointer, addition);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
            // normal multiple registers.
            else if (registersToken >= 0xC0 && registersToken <= 0xFF)
            {
                instruction.operand1 = new Operand(register1, isLEA ? OperandType.LeaRegister : OperandType.Normal);
                instruction.operand2 = new Operand(register2, OperandType.Normal);
            }
        }
Ejemplo n.º 26
0
 internal void ProcessRegisterOperands(x86Instruction instruction)
 {
     switch (instruction.OpCode.GetRegisterOperandType())
     {
         case x86OperandType.Multiple32Register:
         case x86OperandType.Multiple32Or8Register:
         case x86OperandType.Multiple16Register:
         case x86OperandType.RegisterLeaRegister:
             DecodeDoubleRegisters(ref instruction, instruction.code._opcodeBytes[instruction.code._opcodeBytes.Length - 1]);
             break;
         case x86OperandType.Register8:
         case x86OperandType.Register32:
         case x86OperandType.Register32Or8:
             DecodeSingleRegister(ref instruction, instruction.code._opcodeBytes[instruction.code._opcodeBytes.Length - 1]);
             break;
     }
 }
Ejemplo n.º 27
0
        internal void ProcessOverrideOperand(x86Instruction instruction)
        {
            x86OperandType operandType = instruction.OpCode.GetOverrideOperandType();
            if (operandType.HasFlag(x86OperandType.ForceDwordPointer))
            {

                if (instruction.operand2 != null)
                    if (instruction.operand2.Value is uint)
                        instruction.operand2 = CreatePtr((uint)instruction.operand2.Value, OperandType.DwordPointer);
                    else
                        instruction.operand2.ValueType = OperandType.DwordPointer;
                else
                    if (instruction.operand1.Value is uint)
                        instruction.operand1 = CreatePtr((uint)instruction.operand1.Value, OperandType.DwordPointer);
                    else
                        instruction.operand1.ValueType = OperandType.DwordPointer;
            }
            if (operandType.HasFlag(x86OperandType.OverrideOperandOrder))
            {
                Operand temp = instruction.operand1;
                instruction.operand1 = instruction.operand2;
                instruction.operand2 = temp;
            }
        }
Ejemplo n.º 28
0
        private void DecodeSingleRegister(ref x86Instruction instruction, byte registerstoken)
        {
            x86Instruction result = instruction;
            x86OpCode resultopcode = instruction.OpCode;
            resultopcode.opcodebytes[instruction.OpCode.variableByteIndex] = registerstoken;
            result.OpCode = resultopcode;

            int multiplier = (int)Math.Floor(Convert.ToDouble(registerstoken / 0x8));
            int start = multiplier * 0x8;
            int actualregister = registerstoken - start;

            OperandType registerValueType = OperandType.Normal;
            int addition = 0;
            if (registerstoken < 0x8)
            {
                //normal dword pointer
                registerValueType = OperandType.DwordPointer;

            }
            else if (registerstoken >= 0x40 && registerstoken < 0x48)
            {
                //dword pointer + sbyte addition
                registerValueType = OperandType.DwordPointer;
                instruction.operandbytes = new byte[] { image.ReadByte() };
                instruction.OpCode.operandlength = 1;
                addition = ASMGlobals.ByteToSByte(instruction.operandbytes[0]);
            }
            else if (registerstoken >= 0x80 && registerstoken < 0x88)
            {
                //dword pointer + int addition
                registerValueType = OperandType.DwordPointer;
                instruction.operandbytes = image.ReadBytes(4);
                instruction.OpCode.operandlength = 4;
                addition = BitConverter.ToInt32(instruction.operandbytes, 0);
            }
            else if (registerstoken >= 0xC0 && registerstoken < 0xC8)
            {
                // normal register -> do nothing.
            }
            else
            {
                // TODO: Invalid single register token.

            }

            instruction.operand1 = new Operand((x86Register)actualregister, registerValueType, addition);
        }
Ejemplo n.º 29
0
 /// <summary>
 /// Calculates and returns the size in bytes needed when replacing an instruction.
 /// </summary>
 /// <param name="targetInstruction">The instruction to be replaced.</param>
 /// <param name="newInstruction">The new instruction.</param>
 /// <returns></returns>
 public int CalculateSpaceNeeded(x86Instruction targetInstruction, x86Instruction newInstruction)
 {
     return(CalculateSpaceNeeded(targetInstruction, newInstruction.Size));
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Creates an instance of a x86 instruction with two operands.
 /// </summary>
 /// <param name="assembly">The parent assembly.</param>
 /// <param name="opcode">The opcode to use.</param>
 /// <param name="operand1">The first operand to use.</param>
 /// <param name="operand2">The second operand to use.</param>
 /// <returns></returns>
 public static x86Instruction Create(Win32Assembly assembly, x86OpCode opcode, Operand operand1, Operand operand2)
 {
     x86Instruction newInstruction = new x86Instruction(assembly);
     newInstruction.OpCode = opcode;
     newInstruction.operand1 = operand1;
     newInstruction.operand2 = operand2;
     newInstruction.GenerateBytes();
     return newInstruction;
 }
Ejemplo n.º 31
0
        /// <summary>
        /// Disassembles the next instruction at the current offset.
        /// </summary>
        /// <returns></returns>
        public x86Instruction DisassembleNextInstruction()
        {
            x86Instruction newInstruction = new x86Instruction(image.assembly);
            newInstruction.Offset = Offset.FromFileOffset((uint)image.stream.Position, image.assembly);

               // if (newInstruction.offset == 0x6d1f)
               //     System.Diagnostics.Debugger.Break();

            newInstruction.OpCode = RetrieveNextOpCode();
            ProcessVariableByteIndex(ref newInstruction.code);

            newInstruction.operandbytes = ReadRawOperand(newInstruction.OpCode);
            ProcessInstructionBytes(ref newInstruction);

            return newInstruction;
        }
Ejemplo n.º 32
0
 /// <summary>
 /// Adds an instruction to the Assembly Instruction Collection.
 /// </summary>
 /// <param name="instruction">The instruction to add.</param>
 public void Add(x86Instruction instruction)
 {
     List.Add(instruction);
 }
Ejemplo n.º 33
0
 /// <summary>
 /// Calculates and returns the size in bytes needed when replacing an instruction.
 /// </summary>
 /// <param name="targetInstruction">The instruction to be replaced.</param>
 /// <param name="newInstruction">The new instruction.</param>
 /// <returns></returns>
 public int CalculateSpaceNeeded(x86Instruction targetInstruction, x86Instruction newInstruction)
 {
     return CalculateSpaceNeeded(targetInstruction, newInstruction.Size);
 }
Ejemplo n.º 34
0
        private void ProcessOperandBytes(ref x86Instruction instruction)
        {
            uint    nextOffset   = (uint)(instruction.Offset.FileOffset + instruction.Size);
            Operand operandValue = null;

            switch (instruction.OpCode.GetNormalOperandType())
            {
            case x86OperandType.Byte:
                operandValue = new Operand(instruction.operandbytes[0]);
                break;

            case x86OperandType.Word:
                operandValue = new Operand(BitConverter.ToInt16(instruction.operandbytes, 0));
                break;

            case x86OperandType.WordAndByte:
                break;     // TODO

            case x86OperandType.Dword:
                operandValue = new Operand(BitConverter.ToUInt32(instruction.operandbytes, 0));
                break;

            case x86OperandType.Fword:
                break;     // TODO

            case x86OperandType.Qword:
                operandValue = new Operand(BitConverter.ToUInt64(instruction.operandbytes, 0));
                break;

            case x86OperandType.InstructionAddress:
                operandValue = CreateTargetOffset((uint)(nextOffset + BitConverter.ToInt32(instruction.operandbytes, 0)));
                break;

            case x86OperandType.ShortInstructionAddress:
                operandValue = CreateTargetOffset((uint)(nextOffset + ASMGlobals.ByteToSByte(instruction.operandbytes[0])));
                break;

            case x86OperandType.Register32:
                DecodeSingleRegister(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                break;

            case x86OperandType.Instruction:
                // opcode is prefix.
                x86Instruction nextInstruction = DisassembleNextInstruction();
                operandValue                   = new Operand(nextInstruction);
                instruction.operandbytes       = ASMGlobals.MergeBytes(nextInstruction.code.OpCodeBytes, nextInstruction.operandbytes);
                instruction.code.operandlength = nextInstruction.Size;
                break;

            case x86OperandType.None:
                if (instruction.code.IsBasedOn(x86OpCodes.Unknown))
                {
                    operandValue = new Operand(instruction.code.opcodebytes[0]);
                }
                break;
            }

            if (operandValue != null)
            {
                if (instruction.operand1 != null)
                {
                    instruction.operand2 = operandValue;
                }
                else
                {
                    instruction.operand1 = operandValue;
                }
            }
        }
Ejemplo n.º 35
0
        private void ProcessInstructionBytes(ref x86Instruction instruction)
        {
            uint nextOffset = (uint)(instruction.Offset.FileOffset + instruction.Size);
            switch (instruction.code.operandtype)
            {
                case x86OperandType.Byte:
                    instruction.operand1 = new Operand(instruction.operandbytes[0]);
                    break;
                case x86OperandType.DwordPtr:
                    instruction.operand1 = CreatePtr(BitConverter.ToUInt32(instruction.operandbytes, 0), OperandType.DwordPointer);
                    break;
                case x86OperandType.Dword:
                    instruction.operand1 = new Operand(BitConverter.ToUInt32(instruction.operandbytes, 0));
                    break;
                case x86OperandType.InstructionAddress:
                    instruction.operand1 = CreateTargetOffset((uint)(nextOffset + BitConverter.ToInt32(instruction.operandbytes, 0)));
                    break;
                case x86OperandType.ShortInstructionAddress:
                    instruction.operand1 = CreateTargetOffset(nextOffset + instruction.operandbytes[0]);
                    break;
                case x86OperandType.Multiple32Register:
                case x86OperandType.Multiple32Or8Register:
                case x86OperandType.Multiple16Register:
                case x86OperandType.RegisterLeaRegister:
                    DecodeDoubleRegisters(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                    break;
                case x86OperandType.Qword:
                    instruction.operand1 = new Operand(BitConverter.ToUInt64(instruction.operandbytes, 0));
                    break;
                case x86OperandType.Register:
                    DecodeSingleRegister(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                    break;
                case x86OperandType.RegisterAndDword:
                    DecodeSingleRegister(ref instruction, instruction.code.opcodebytes[instruction.code.opcodebytes.Length - 1]);
                    instruction.operand2 = new Operand(BitConverter.ToInt32(instruction.operandbytes, 0));
                    break;
                case x86OperandType.RegisterAndByte:
                case x86OperandType.RegisterOffset:
                case x86OperandType.RegisterPointer:
                case x86OperandType.Word:
                case x86OperandType.WordAndByte:

                case x86OperandType.Fword:
                case x86OperandType.FwordPtr:
                    break;
                case x86OperandType.Instruction:
                    // opcode is prefix.
                    x86Instruction nextInstruction = DisassembleNextInstruction();
                    instruction.operand1 = new Operand(nextInstruction);
                    instruction.operandbytes = ASMGlobals.MergeBytes(nextInstruction.code.OpCodeBytes, nextInstruction.operandbytes);
                    instruction.code.operandlength = nextInstruction.Size;
                    break;
                case x86OperandType.None:
                    if (instruction.code.IsBasedOn(x86OpCodes.Unknown))
                        instruction.operand1 = new Operand(instruction.code.opcodebytes[0]);
                    break;
            }
        }
Ejemplo n.º 36
0
        private void DecodeSingleRegister(ref x86Instruction instruction, byte registerstoken)
        {
            x86Instruction result       = instruction;
            x86OpCode      resultopcode = instruction.OpCode;

            resultopcode.opcodebytes[instruction.OpCode.variableByteIndex] = registerstoken;
            result.OpCode = resultopcode;

            bool isGroupOpCode = MatchWithOpCodes(instruction.OpCode.opcodebytes[0]).Length > 1;

            int actualregister = registerstoken % 8;

            OperandType registerValueType = OperandType.Normal;
            int         addition          = 0;

            if (registerstoken < 0x40)
            {
                //normal dword pointer
                if (!isGroupOpCode && registerstoken >= 0x8)
                {
                    ProcessInvalidInstruction(ref instruction);
                    return;
                }
                registerValueType = OperandType.DwordPointer;
            }
            else if (registerstoken >= 0x40 && registerstoken < 0x80)
            {
                //dword pointer + sbyte addition
                if (!isGroupOpCode && registerstoken >= 0x48)
                {
                    ProcessInvalidInstruction(ref instruction);
                    return;
                }
                registerValueType                = OperandType.DwordPointer;
                instruction.operandbytes         = new byte[] { reader.ReadByte() };
                instruction.OpCode.operandlength = 1;
                addition = ASMGlobals.ByteToSByte(instruction.operandbytes[0]);
            }
            else if (registerstoken >= 0x80 && registerstoken < 0xC0)
            {
                //dword pointer + int addition
                if (!isGroupOpCode && registerstoken >= 0x88)
                {
                    ProcessInvalidInstruction(ref instruction);
                    return;
                }
                registerValueType                = OperandType.DwordPointer;
                instruction.operandbytes         = reader.ReadBytes(4);
                instruction.OpCode.operandlength = 4;
                addition = BitConverter.ToInt32(instruction.operandbytes, 0);
            }
            else if (registerstoken >= 0xC0 && registerstoken <= 0xFF)
            {
                // normal register -> do nothing.
                if (!isGroupOpCode && registerstoken >= 0xC8)
                {
                    ProcessInvalidInstruction(ref instruction);
                    return;
                }
            }
            else
            {
                // TODO: Invalid single register token.
            }
            if (instruction.OpCode.operandtype.HasFlag(x86OperandType.Register8))
            {
                actualregister |= (byte)x86Register.Bit8Mask;
            }
            instruction.operand1 = new Operand((x86Register)actualregister, registerValueType, addition);
        }
Ejemplo n.º 37
0
 /// <summary>
 /// Replaces an instruction with a new instruction.
 /// </summary>
 /// <param name="targetInstruction">The instruction to replace.</param>
 /// <param name="newInstruction">The new instruction.</param>
 public void Replace(x86Instruction targetInstruction, x86Instruction newInstruction)
 {
     Replace(targetInstruction, newInstruction, false);
 }
Ejemplo n.º 38
0
        private void DecodeSingleRegister(ref x86Instruction instruction, byte registersToken)
        {
            x86Instruction result = instruction;
            x86OpCode resultopcode = instruction.OpCode;
            resultopcode._opcodeBytes[instruction.OpCode._variableByteIndex] = registersToken;
            result.OpCode = resultopcode;

            bool isGroupOpCode = MatchWithOpCodes(instruction.OpCode._opcodeBytes[0]).Length > 1;

            int actualregister = registersToken % 8;

            OperandType registerValueType = OperandType.Normal;
            int addition = 0;
            if (registersToken < 0x40)
            {
                //normal dword pointer
                if (!isGroupOpCode && registersToken >= 0x8)
                {
                    ProcessInvalidInstruction(instruction);
                    return;
                }
                registerValueType = OperandType.DwordPointer;

            }
            else if (registersToken >= 0x40 && registersToken < 0x80)
            {
                //dword pointer + sbyte addition
                if (!isGroupOpCode && registersToken >= 0x48)
                {
                    ProcessInvalidInstruction(instruction);
                    return;
                }
                registerValueType = OperandType.DwordPointer;
                instruction.operandbytes = new byte[] { reader.ReadByte() };
                instruction.OpCode._operandLength++;
                addition = ASMGlobals.ByteToSByte(instruction.operandbytes[0]);
            }
            else if (registersToken >= 0x80 && registersToken < 0xC0)
            {
                //dword pointer + int addition
                if (!isGroupOpCode && registersToken >= 0x88)
                {
                    ProcessInvalidInstruction(instruction);
                    return;
                }
                registerValueType = OperandType.DwordPointer;
                instruction.operandbytes = reader.ReadBytes(4);
                instruction.OpCode._operandLength += 4;
                addition = BitConverter.ToInt32(instruction.operandbytes, 0);
            }
            else if (registersToken >= 0xC0 && registersToken <= 0xFF)
            {
                // normal register -> do nothing.
                if (!isGroupOpCode && registersToken >= 0xC8)
                {
                    ProcessInvalidInstruction(instruction);
                    return;
                }
            }
            else
            {
                // TODO: Invalid single register token.

            }
            if (instruction.OpCode._operandType.HasFlag(x86OperandType.Register8))
            {
                actualregister |= (byte)x86Register.Bit8Mask;
            }
            if (instruction.OpCode._operandType.HasFlag(x86OperandType.Register32Or8))
            {
                actualregister |= GetSingleRegisterMask(registersToken);
            }

            instruction.operand1 = new Operand((x86Register)actualregister, registerValueType, addition);
        }
Ejemplo n.º 39
0
 internal void ProcessInvalidInstruction(x86Instruction instruction)
 {
     byte firstByte = instruction.OpCode.OpCodeBytes[0];
     instruction.OpCode = x86OpCode.Create(x86OpCodes.Unknown);
     instruction.OpCode._opcodeBytes = new byte[] { firstByte };
     CurrentOffset = instruction.Offset.FileOffset + 1;
 }
Ejemplo n.º 40
0
 /// <summary>
 /// Replaces an instruction with a new instruction.
 /// </summary>
 /// <param name="targetInstruction">The instruction to replace.</param>
 /// <param name="newInstruction">The new instruction.</param>
 public void Replace(x86Instruction targetInstruction, x86Instruction newInstruction)
 {
     Replace(targetInstruction, newInstruction, false);
 }
 /// <summary>
 /// Adds an instruction to the Assembly Instruction Collection.
 /// </summary>
 /// <param name="instruction">The instruction to add.</param>
 public void Add(x86Instruction instruction)
 {
     List.Add(instruction);
 }