Пример #1
0
        public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction, bool overwriteWhenLarger, bool suppressInvalidReferences)
        {
            int targetOffset = (int)(_bodyOffset + targetInstruction.Offset);

            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;
            GenerateOperandBytes(newInstruction);

            if (!suppressInvalidReferences && newInstruction.Operand is MetaDataMember)
            {
                if (!ValidateReference(newInstruction.Operand as MetaDataMember))
                    throw new ArgumentException(newInstruction.Operand.ToString() + " does not match with the metadata member provided in the target assembly", "newInstruction");
            }

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

            _image.SetOffset(targetOffset);
            _image.Writer.Write(newInstruction.OpCode.Bytes);
            if (newInstruction.OperandBytes != null)
                _image.Writer.Write(newInstruction.OperandBytes);

            _image.Writer.Write(NOPS);
        }
Пример #2
0
        public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction, bool overwriteWhenLarger, bool suppressInvalidReferences)
        {
            int targetOffset = (int)(_bodyOffset + targetInstruction.Offset);

            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;
            GenerateOperandBytes(newInstruction);

            if (!suppressInvalidReferences && newInstruction.Operand is MetaDataMember)
            {
                if (!ValidateReference(newInstruction.Operand as MetaDataMember))
                {
                    throw new ArgumentException(newInstruction.Operand.ToString() + " does not match with the metadata member provided in the target assembly", "newInstruction");
                }
            }

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

            byte[] NOPS = new byte[NopsToAdd];

            _image.SetOffset(targetOffset);
            _image.Writer.Write(newInstruction.OpCode.Bytes);
            if (newInstruction.OperandBytes != null)
            {
                _image.Writer.Write(newInstruction.OperandBytes);
            }

            _image.Writer.Write(NOPS);
        }
Пример #3
0
        public static MSILInstruction Create(MSILOpCode opcode, object operand)
        {
            MSILInstruction instruction = new MSILInstruction()
            {
                OpCode  = opcode,
                Operand = operand,
            };

            return(instruction);
        }
Пример #4
0
 private void SetBranchTargets(List <MSILInstruction> instructions)
 {
     for (int i = 0; i < instructions.Count; i++)
     {
         MSILInstruction instruction = instructions[i];
         if (instruction.OpCode.OperandType == OperandType.InstructionTarget || instruction.OpCode.OperandType == OperandType.ShortInstructionTarget)
         {
             int             targetOffset      = (int)instruction.Operand;
             MSILInstruction targetInstruction = instructions.FirstOrDefault(t => t.Offset == targetOffset);
             if (targetInstruction != null)
             {
                 instructions[i].Operand = targetInstruction;
             }
         }
     }
 }
Пример #5
0
        public int CalculateSpaceNeeded(MSILInstruction targetInstruction, int newSize)
        {
            if (newSize <= targetInstruction.Size)
                return targetInstruction.Size;

            int sizeNeeded = 0;

            int currentOffset = targetInstruction.Offset;
            while (sizeNeeded < newSize)
            {
                _disassembler.CurrentOffset = currentOffset;
                MSILInstruction currentInstruction = _disassembler.DisassembleNextInstruction();
                sizeNeeded += currentInstruction.Size;
                currentOffset += currentInstruction.Size;
            }
            return sizeNeeded;
        }
Пример #6
0
        public MSILInstruction[] Disassemble(int startoffset, int length)
        {
            List <MSILInstruction> instructions = new List <MSILInstruction>();

            _reader.BaseStream.Position = _ilOffset + startoffset;
            int currentOffset = 0;

            while (_reader.BaseStream.Position < _ilOffset + startoffset + length)
            {
                MSILInstruction instruction = DisassembleNextInstruction();
                instructions.Add(instruction);
                currentOffset += instruction.Size;
                _reader.BaseStream.Position = _ilOffset + startoffset + currentOffset;
            }
            SetEnclosingInstructions(instructions);
            SetBranchTargets(instructions);
            return(instructions.ToArray());
        }
Пример #7
0
        public int CalculateSpaceNeeded(MSILInstruction targetInstruction, int newSize)
        {
            if (newSize <= targetInstruction.Size)
            {
                return(targetInstruction.Size);
            }

            int sizeNeeded = 0;

            int currentOffset = targetInstruction.Offset;

            while (sizeNeeded < newSize)
            {
                _disassembler.CurrentOffset = currentOffset;
                MSILInstruction currentInstruction = _disassembler.DisassembleNextInstruction();
                sizeNeeded    += currentInstruction.Size;
                currentOffset += currentInstruction.Size;
            }
            return(sizeNeeded);
        }
Пример #8
0
 public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction, bool overwriteWhenLarger)
 {
     Replace(targetInstruction, newInstruction, overwriteWhenLarger, false);
 }
Пример #9
0
 public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction)
 {
     Replace(targetInstruction, newInstruction, false, false);
 }
Пример #10
0
 public int CalculateSpaceNeeded(MSILInstruction targetInstruction, MSILInstruction newInstruction)
 {
     return CalculateSpaceNeeded(targetInstruction, newInstruction.Size);
 }
Пример #11
0
        internal void GenerateOperandBytes(MSILInstruction instruction)
        {
            if (instruction.OperandBytes == null)
            {
                switch (instruction.OpCode.OperandType)
                {
                    case OperandType.Argument:
                        if (instruction.Operand is ParameterDefinition)
                            instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as ParameterDefinition).Sequence);
                        break;
                    case OperandType.ShortArgument:
                        if (instruction.Operand is ParameterDefinition)
                            instruction.OperandBytes = BitConverter.GetBytes((byte)(instruction.Operand as ParameterDefinition).Sequence);
                        break;
                    case OperandType.Variable:
                        if (instruction.Operand is VariableDefinition)
                            instruction.OperandBytes = BitConverter.GetBytes((ushort)(instruction.Operand as VariableDefinition).Index);
                        break;
                    case OperandType.ShortVariable:
                        if (instruction.Operand is VariableDefinition)
                            instruction.OperandBytes = BitConverter.GetBytes((byte)(instruction.Operand as VariableDefinition).Index);
                        break;
                    case OperandType.Field:
                    case OperandType.Token:
                    case OperandType.Method:
                    case OperandType.Type:
                        // TODO: importing metadata Members into tablesheap
                        if (instruction.Operand is MetaDataMember)
                            instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as MetaDataMember)._metadatatoken);
                        break;
                    case OperandType.Float32:
                        if (instruction.Operand is float)
                            instruction.OperandBytes = BitConverter.GetBytes((float)instruction.Operand);
                        break;
                    case OperandType.Float64:
                        if (instruction.Operand is double)
                            instruction.OperandBytes = BitConverter.GetBytes((double)instruction.Operand);
                        break;
                    case OperandType.Int8:
                        if (instruction.Operand is sbyte)
                            instruction.OperandBytes = new byte[] { byte.Parse(((byte)instruction.Operand).ToString("x2"), System.Globalization.NumberStyles.HexNumber) };
                        break;
                    case OperandType.Signature:
                    case OperandType.Int32:
                        if (instruction.Operand is int)
                            instruction.OperandBytes = BitConverter.GetBytes((int)instruction.Operand);
                        break;
                    case OperandType.Int64:
                        if (instruction.Operand is long)
                            instruction.OperandBytes = BitConverter.GetBytes((long)instruction.Operand);
                        break;
                    case OperandType.InstructionTarget:
                        //BitConverter.ToInt32(rawoperand,0) + instructionOffset + opcode.Bytes.Length + sizeof(int);
                        if (instruction.Operand is MSILInstruction)
                            instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as MSILInstruction).Offset - sizeof(int) - instruction.OpCode.Bytes.Length - instruction.Offset);
                        break;
                    case OperandType.ShortInstructionTarget:
                        if (instruction.Operand is MSILInstruction)
                            instruction.OperandBytes = new byte[] { byte.Parse(((sbyte)((instruction.Operand as MSILInstruction).Offset - sizeof(sbyte) - instruction.OpCode.Bytes.Length - instruction.Offset)).ToString("x2"), System.Globalization.NumberStyles.HexNumber) };
                        break;
                    case OperandType.String:
                        //TODO: importing strings into stringsheap

                    case OperandType.Phi:
                    case OperandType.InstructionTable:
                        throw new NotSupportedException();

                }
                if (instruction.OperandBytes == null && instruction.Operand != null)
                    throw new ArgumentException("Operand must match with the opcode's operand type (" + instruction.OpCode.OperandType.ToString() + ")");
            }
        }
Пример #12
0
 public int CalculateSpaceNeeded(MSILInstruction targetInstruction, MSILInstruction newInstruction)
 {
     return(CalculateSpaceNeeded(targetInstruction, newInstruction.Size));
 }
Пример #13
0
 public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction, bool overwriteWhenLarger)
 {
     Replace(targetInstruction, newInstruction, overwriteWhenLarger, false);
 }
Пример #14
0
 public void Replace(MSILInstruction targetInstruction, MSILInstruction newInstruction)
 {
     Replace(targetInstruction, newInstruction, false, false);
 }
Пример #15
0
        internal void GenerateOperandBytes(MSILInstruction instruction)
        {
            if (instruction.OperandBytes == null)
            {
                switch (instruction.OpCode.OperandType)
                {
                case OperandType.Argument:
                    if (instruction.Operand is ParameterDefinition)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as ParameterDefinition).Sequence);
                    }
                    break;

                case OperandType.ShortArgument:
                    if (instruction.Operand is ParameterDefinition)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((byte)(instruction.Operand as ParameterDefinition).Sequence);
                    }
                    break;

                case OperandType.Variable:
                    if (instruction.Operand is VariableDefinition)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((ushort)(instruction.Operand as VariableDefinition).Index);
                    }
                    break;

                case OperandType.ShortVariable:
                    if (instruction.Operand is VariableDefinition)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((byte)(instruction.Operand as VariableDefinition).Index);
                    }
                    break;

                case OperandType.Field:
                case OperandType.Token:
                case OperandType.Method:
                case OperandType.Type:
                    // TODO: importing metadata Members into tablesheap
                    if (instruction.Operand is MetaDataMember)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as MetaDataMember)._metadatatoken);
                    }
                    break;

                case OperandType.Float32:
                    if (instruction.Operand is float)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((float)instruction.Operand);
                    }
                    break;

                case OperandType.Float64:
                    if (instruction.Operand is double)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((double)instruction.Operand);
                    }
                    break;

                case OperandType.Int8:
                    if (instruction.Operand is sbyte)
                    {
                        instruction.OperandBytes = new byte[] { byte.Parse(((byte)instruction.Operand).ToString("x2"), System.Globalization.NumberStyles.HexNumber) }
                    }
                    ;
                    break;

                case OperandType.Signature:
                case OperandType.Int32:
                    if (instruction.Operand is int)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((int)instruction.Operand);
                    }
                    break;

                case OperandType.Int64:
                    if (instruction.Operand is long)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((long)instruction.Operand);
                    }
                    break;

                case OperandType.InstructionTarget:
                    //BitConverter.ToInt32(rawoperand,0) + instructionOffset + opcode.Bytes.Length + sizeof(int);
                    if (instruction.Operand is MSILInstruction)
                    {
                        instruction.OperandBytes = BitConverter.GetBytes((instruction.Operand as MSILInstruction).Offset - sizeof(int) - instruction.OpCode.Bytes.Length - instruction.Offset);
                    }
                    break;

                case OperandType.ShortInstructionTarget:
                    if (instruction.Operand is MSILInstruction)
                    {
                        instruction.OperandBytes = new byte[] { byte.Parse(((sbyte)((instruction.Operand as MSILInstruction).Offset - sizeof(sbyte) - instruction.OpCode.Bytes.Length - instruction.Offset)).ToString("x2"), System.Globalization.NumberStyles.HexNumber) }
                    }
                    ;
                    break;

                case OperandType.String:
                //TODO: importing strings into stringsheap

                case OperandType.Phi:
                case OperandType.InstructionTable:
                    throw new NotSupportedException();
                }
                if (instruction.OperandBytes == null && instruction.Operand != null)
                {
                    throw new ArgumentException("Operand must match with the opcode's operand type (" + instruction.OpCode.OperandType.ToString() + ")");
                }
            }
        }
Пример #16
0
 public static MSILInstruction Create(MSILOpCode opcode, object operand)
 {
     MSILInstruction instruction = new MSILInstruction()
     {
         OpCode = opcode,
         Operand = operand,
     };
     return instruction;
 }