Example #1
0
        void EncodeDeclareByte(string hexBytes)
        {
            const int   bitness = 64;
            const ulong newRip  = 0x8000000000000000;

            var data         = HexUtils.ToByteArray(hexBytes);
            var instructions = new Instruction[] {
                Instruction.Create(Code.Nopd),
                Instruction.CreateDeclareByte(data),
                Instruction.Create(Code.Nopd),
            };

            var expectedData = new byte[data.Length + 2];

            expectedData[0] = 0x90;
            Array.Copy(data, 0, expectedData, 1, data.Length);
            expectedData[expectedData.Length - 1] = 0x90;

            var  codeWriter = new CodeWriterImpl();
            bool b          = BlockEncoder.TryEncode(bitness, new InstructionBlock(codeWriter, instructions, newRip), out var errorMessage, out var result);

            Assert.True(b);
            Assert.Null(errorMessage);
            Assert.Equal(expectedData, codeWriter.ToArray());
            Assert.Equal(newRip, result.RIP);
            Assert.Null(result.RelocInfos);
            Assert.NotNull(result.NewInstructionOffsets);
            Assert.True(result.NewInstructionOffsets.Length == 0);
            Assert.NotNull(result.ConstantOffsets);
            Assert.True(result.ConstantOffsets.Length == 0);
        }
Example #2
0
        protected void EncodeInvalidBase(int codeSize, Code code, string hexBytes, int invalidCodeSize)
        {
            var origBytes = HexUtils.ToByteArray(hexBytes);
            var decoder   = CreateDecoder(codeSize, origBytes);
            var origRip   = decoder.InstructionPointer;
            var origInstr = decoder.Decode();

            Assert.Equal(code, origInstr.Code);
            Assert.Equal(origBytes.Length, origInstr.ByteLength);
            Assert.True(origInstr.ByteLength <= Iced.Intel.DecoderConstants.MaxInstructionLength);
            Assert.Equal((ushort)origRip, origInstr.IP16);
            Assert.Equal((uint)origRip, origInstr.IP32);
            Assert.Equal(origRip, origInstr.IP64);
            var afterRip = decoder.InstructionPointer;

            Assert.Equal((ushort)afterRip, origInstr.NextIP16);
            Assert.Equal((uint)afterRip, origInstr.NextIP32);
            Assert.Equal(afterRip, origInstr.NextIP64);

            var writer          = new CodeWriterImpl();
            var encoder         = CreateEncoder(invalidCodeSize, writer);
            var origInstrCopy   = origInstr;
            int encodedInstrLen = encoder.Encode(ref origInstr, origRip, out string errorMessage);

            Assert.True(errorMessage == Encoder.ERROR_ONLY_1632_BIT_MODE || errorMessage == Encoder.ERROR_ONLY_64_BIT_MODE);
            Assert.True(Instruction.TEST_BitByBitEquals(ref origInstr, ref origInstrCopy));
            Assert.True(encodedInstrLen >= 0);
        }
Example #3
0
        protected void NonDecodeEncodeBase(int codeSize, ref Instruction instr, string hexBytes, ulong rip)
        {
            var expectedBytes = HexUtils.ToByteArray(hexBytes);
            var writer        = new CodeWriterImpl();
            var encoder       = Encoder.Create(codeSize, writer);

            Assert.Equal(codeSize, encoder.Bitness);
            var  origInstrCopy = instr;
            bool result        = encoder.TryEncode(instr, rip, out uint encodedInstrLen, out string errorMessage);

            Assert.True(errorMessage is null, "Unexpected ErrorMessage: " + errorMessage);
            Assert.True(result, "Error, result from Encoder.TryEncode must be true");
            var encodedBytes = writer.ToArray();

            Assert.Equal(encodedBytes.Length, (int)encodedInstrLen);
            Assert.True(Instruction.TEST_BitByBitEquals(instr, origInstrCopy));
            if (!ArrayEquals(expectedBytes, encodedBytes))
            {
#pragma warning disable xUnit2006 // Do not use invalid string equality check
                // Show the full string without ellipses by using Equal<string>() instead of Equal()
                Assert.Equal <string>(ToString(expectedBytes), ToString(encodedBytes));
                throw new InvalidOperationException();
#pragma warning restore xUnit2006 // Do not use invalid string equality check
            }
        }
Example #4
0
        protected void EncodeInvalidBase(int codeSize, Code code, string hexBytes, DecoderOptions options, int invalidCodeSize)
        {
            var origBytes = HexUtils.ToByteArray(hexBytes);
            var decoder   = CreateDecoder(codeSize, origBytes, options);
            var origRip   = decoder.IP;
            var origInstr = decoder.Decode();

            Assert.Equal(code, origInstr.Code);
            Assert.Equal(origBytes.Length, origInstr.ByteLength);
            Assert.True(origInstr.ByteLength <= Iced.Intel.DecoderConstants.MaxInstructionLength);
            Assert.Equal((ushort)origRip, origInstr.IP16);
            Assert.Equal((uint)origRip, origInstr.IP32);
            Assert.Equal(origRip, origInstr.IP);
            var afterRip = decoder.IP;

            Assert.Equal((ushort)afterRip, origInstr.NextIP16);
            Assert.Equal((uint)afterRip, origInstr.NextIP32);
            Assert.Equal(afterRip, origInstr.NextIP);

            var  writer        = new CodeWriterImpl();
            var  encoder       = CreateEncoder(invalidCodeSize, writer);
            var  origInstrCopy = origInstr;
            bool result        = encoder.TryEncode(origInstr, origRip, out uint encodedInstrLen, out string errorMessage);

            Assert.Equal(invalidCodeSize == 64 ? Encoder.ERROR_ONLY_1632_BIT_MODE : Encoder.ERROR_ONLY_64_BIT_MODE, errorMessage);
            Assert.False(result);
            Assert.True(Instruction.TEST_BitByBitEquals(origInstr, origInstrCopy));
        }
Example #5
0
        protected void EncodeBase(uint id, int bitness, Code code, string hexBytes, string encodedHexBytes, DecoderOptions options)
        {
            var origBytes           = HexUtils.ToByteArray(hexBytes);
            var decoder             = CreateDecoder(bitness, origBytes, options);
            var origRip             = decoder.IP;
            var origInstr           = decoder.Decode();
            var origConstantOffsets = decoder.GetConstantOffsets(origInstr);

            Assert.Equal(code, origInstr.Code);
            Assert.Equal(origBytes.Length, origInstr.Length);
            Assert.True(origInstr.Length <= IcedConstants.MaxInstructionLength);
            Assert.Equal((ushort)origRip, origInstr.IP16);
            Assert.Equal((uint)origRip, origInstr.IP32);
            Assert.Equal(origRip, origInstr.IP);
            var afterRip = decoder.IP;

            Assert.Equal((ushort)afterRip, origInstr.NextIP16);
            Assert.Equal((uint)afterRip, origInstr.NextIP32);
            Assert.Equal(afterRip, origInstr.NextIP);

            var writer  = new CodeWriterImpl();
            var encoder = Encoder.Create(decoder.Bitness, writer);

            Assert.Equal(bitness, encoder.Bitness);
            var  origInstrCopy = origInstr;
            bool result        = encoder.TryEncode(origInstr, origRip, out uint encodedInstrLen, out string errorMessage);

            Assert.True(errorMessage is null, "Unexpected error message: " + errorMessage);
            Assert.True(result, "Error, result from Encoder.TryEncode must be true");
            var encodedConstantOffsets = encoder.GetConstantOffsets();

            FixConstantOffsets(ref encodedConstantOffsets, origInstr.Length, (int)encodedInstrLen);
            Assert.True(Equals(ref origConstantOffsets, ref encodedConstantOffsets));
            var encodedBytes = writer.ToArray();

            Assert.Equal(encodedBytes.Length, (int)encodedInstrLen);
            Assert.True(Instruction.EqualsAllBits(origInstr, origInstrCopy));

            var expectedBytes = HexUtils.ToByteArray(encodedHexBytes);

            if (!ArrayEquals(expectedBytes, encodedBytes))
            {
#pragma warning disable xUnit2006 // Do not use invalid string equality check
                // Show the full string without ellipses by using Equal<string>() instead of Equal()
                Assert.Equal <string>(ToString(expectedBytes), ToString(encodedBytes));
                throw new InvalidOperationException();
#pragma warning restore xUnit2006 // Do not use invalid string equality check
            }

            var newInstr = CreateDecoder(bitness, encodedBytes, options).Decode();
            Assert.Equal(code, newInstr.Code);
            Assert.Equal(encodedBytes.Length, newInstr.Length);
            newInstr.Length = origInstr.Length;
            newInstr.NextIP = origInstr.NextIP;
            if (origBytes.Length != expectedBytes.Length && (origInstr.MemoryBase == Register.EIP || origInstr.MemoryBase == Register.RIP))
            {
                newInstr.MemoryDisplacement += (uint)(expectedBytes.Length - origBytes.Length);
            }
            Assert.True(Instruction.EqualsAllBits(origInstr, newInstr));
        }
Example #6
0
        void DefaultArgs()
        {
            const int   bitness = 64;
            const ulong origRip = 0x123456789ABCDE00;
            const ulong newRip  = 0x8000000000000000;

            var originalData = new byte[] {
                /*0000*/ 0xB0, 0x00,                   // mov al,0
                /*0002*/ 0xEB, 0x09,                   // jmp short 123456789ABCDE0Dh
                /*0004*/ 0xB0, 0x01,                   // mov al,1
                /*0006*/ 0xE9, 0x03, 0x00, 0x00, 0x00, // jmp near ptr 123456789ABCDE0Eh
                /*000B*/ 0xB0, 0x02,                   // mov al,2
            };
            var  instructions = BlockEncoderTest.Decode(bitness, origRip, originalData, DecoderOptions.None);
            var  codeWriter   = new CodeWriterImpl();
            bool b            = BlockEncoder.TryEncode(bitness, new InstructionBlock(codeWriter, instructions, newRip), out var errorMessage, out var result);

            Assert.True(b);
            Assert.Null(errorMessage);
            Assert.Equal(newRip, result.RIP);
            Assert.Equal(0x28, codeWriter.ToArray().Length);
            Assert.Null(result.RelocInfos);
            Assert.NotNull(result.NewInstructionOffsets);
            Assert.True(result.NewInstructionOffsets.Length == 0);
            Assert.NotNull(result.ConstantOffsets);
            Assert.True(result.ConstantOffsets.Length == 0);
        }
Example #7
0
        protected void EncodeBase(int codeSize, Code code, string hexBytes, string encodedHexBytes, DecoderOptions options)
        {
            var origBytes           = HexUtils.ToByteArray(hexBytes);
            var decoder             = CreateDecoder(codeSize, origBytes, options);
            var origRip             = decoder.IP;
            var origInstr           = decoder.Decode();
            var origConstantOffsets = decoder.GetConstantOffsets(origInstr);

            Assert.Equal(code, origInstr.Code);
            Assert.Equal(origBytes.Length, origInstr.ByteLength);
            Assert.True(origInstr.ByteLength <= Iced.Intel.DecoderConstants.MaxInstructionLength);
            Assert.Equal((ushort)origRip, origInstr.IP16);
            Assert.Equal((uint)origRip, origInstr.IP32);
            Assert.Equal(origRip, origInstr.IP);
            var afterRip = decoder.IP;

            Assert.Equal((ushort)afterRip, origInstr.NextIP16);
            Assert.Equal((uint)afterRip, origInstr.NextIP32);
            Assert.Equal(afterRip, origInstr.NextIP);

            var writer  = new CodeWriterImpl();
            var encoder = Encoder.Create(decoder.Bitness, writer);

            Assert.Equal(codeSize, encoder.Bitness);
            var  origInstrCopy = origInstr;
            bool result        = encoder.TryEncode(origInstr, origRip, out uint encodedInstrLen, out string errorMessage);

            Assert.True(errorMessage is null, "Unexpected ErrorMessage: " + errorMessage);
            Assert.True(result, "Error, result from Encoder.TryEncode must be true");
            var encodedConstantOffsets = encoder.GetConstantOffsets();

            FixConstantOffsets(ref encodedConstantOffsets, origInstr.ByteLength, (int)encodedInstrLen);
            Assert.True(Equals(ref origConstantOffsets, ref encodedConstantOffsets));
            var encodedBytes = writer.ToArray();

            Assert.Equal(encodedBytes.Length, (int)encodedInstrLen);
            Assert.True(Instruction.TEST_BitByBitEquals(origInstr, origInstrCopy));

            var expectedBytes = HexUtils.ToByteArray(encodedHexBytes);

            if (!ArrayEquals(expectedBytes, encodedBytes))
            {
#pragma warning disable xUnit2006 // Do not use invalid string equality check
                // Show the full string without ellipses by using Equal<string>() instead of Equal()
                Assert.Equal <string>(ToString(expectedBytes), ToString(encodedBytes));
                throw new InvalidOperationException();
#pragma warning restore xUnit2006 // Do not use invalid string equality check
            }

            var newInstr = CreateDecoder(codeSize, encodedBytes, options).Decode();
            Assert.Equal(code, newInstr.Code);
            Assert.Equal(encodedBytes.Length, newInstr.ByteLength);
            newInstr.ByteLength = origInstr.ByteLength;
            newInstr.NextIP     = origInstr.NextIP;
            Assert.True(Instruction.TEST_BitByBitEquals(origInstr, newInstr));
            // Some tests use useless or extra prefixes, so we can't verify the exact length
            Assert.True(encodedBytes.Length <= origBytes.Length, "Unexpected encoded prefixes: " + ToString(encodedBytes));
        }
Example #8
0
        void DisplSize_eq_1_uses_long_form_if_it_does_not_fit_in_1_byte(int bitness, string hexBytes, ulong rip, Instruction instruction)
        {
            var expectedBytes = HexUtils.ToByteArray(hexBytes);
            var codeWriter    = new CodeWriterImpl();
            var encoder       = Encoder.Create(bitness, codeWriter);

            Assert.True(encoder.TryEncode(ref instruction, rip, out uint encodedLength, out string errorMessage), $"Could not encode {instruction}, error: {errorMessage}");
            Assert.Equal(expectedBytes, codeWriter.ToArray());
            Assert.Equal((uint)expectedBytes.Length, encodedLength);
        }
Example #9
0
        protected void EncodeBase(int codeSize, Code code, string hexBytes, DecoderOptions options)
        {
            var origBytes           = HexUtils.ToByteArray(hexBytes);
            var decoder             = CreateDecoder(codeSize, origBytes, options);
            var origRip             = decoder.InstructionPointer;
            var origInstr           = decoder.Decode();
            var origConstantOffsets = decoder.GetConstantOffsets(ref origInstr);

            Assert.Equal(code, origInstr.Code);
            Assert.Equal(origBytes.Length, origInstr.ByteLength);
            Assert.True(origInstr.ByteLength <= Iced.Intel.DecoderConstants.MaxInstructionLength);
            Assert.Equal((ushort)origRip, origInstr.IP16);
            Assert.Equal((uint)origRip, origInstr.IP32);
            Assert.Equal(origRip, origInstr.IP64);
            var afterRip = decoder.InstructionPointer;

            Assert.Equal((ushort)afterRip, origInstr.NextIP16);
            Assert.Equal((uint)afterRip, origInstr.NextIP32);
            Assert.Equal(afterRip, origInstr.NextIP64);

            var writer  = new CodeWriterImpl();
            var encoder = decoder.CreateEncoder(writer);

            Assert.Equal(codeSize, encoder.Bitness);
            var  origInstrCopy = origInstr;
            bool result        = encoder.TryEncode(ref origInstr, origRip, out uint encodedInstrLen, out string errorMessage);

            Assert.True(errorMessage == null, "Unexpected ErrorMessage: " + errorMessage);
            Assert.True(result, "Error, result from Encoder.TryEncode must be true");
            var encodedConstantOffsets = encoder.GetConstantOffsets();

            FixConstantOffsets(ref encodedConstantOffsets, origInstr.ByteLength, (int)encodedInstrLen);
            Assert.True(Equals(ref origConstantOffsets, ref encodedConstantOffsets));
            var encodedBytes = writer.ToArray();

            Assert.Equal(encodedBytes.Length, (int)encodedInstrLen);
            Assert.True(Instruction.TEST_BitByBitEquals(origInstr, origInstrCopy), "Instruction are differing: " + Instruction.TEST_DumpDiff(origInstr, origInstrCopy));

            // We don't compare the generated bytes, bit by bit, for many reasons. Eg. prefixes
            // can be put in any order. Unused prefixes. [xxxx] can be encoded w/ and w/o a sib
            // byte in 32-bit mode. The decoder-tests test ignored bits by setting them to 1, but
            // the encoder always writes 0.
            // The instruction is decoded again and then it's compared against the old one to
            // make sure it matches exactly, bit by bit.

            var newInstr = CreateDecoder(codeSize, encodedBytes, options).Decode();

            Assert.Equal(code, newInstr.Code);
            Assert.Equal(encodedBytes.Length, newInstr.ByteLength);
            newInstr.ByteLength = origInstr.ByteLength;
            newInstr.NextIP64   = origInstr.NextIP64;
            Assert.True(Instruction.TEST_BitByBitEquals(origInstr, newInstr), "Instruction are differing: " + Instruction.TEST_DumpDiff(origInstr, newInstr));
            // Some tests use useless or extra prefixes, so we can't verify the exact length
            Assert.True(encodedBytes.Length <= origBytes.Length, "Unexpected encoded prefixes: " + HexUtils.ToString(encodedBytes));
        }
Example #10
0
        void WriteByte_works()
        {
            var codeWriter  = new CodeWriterImpl();
            var encoder     = Encoder.Create(64, codeWriter);
            var instruction = Instruction.Create(Code.Add_r64_rm64, Register.R8, Register.RBP);

            encoder.WriteByte(0x90);
            encoder.Encode(instruction, 0x55555555);
            encoder.WriteByte(0xCC);
            Assert.Equal(new byte[] { 0x90, 0x4C, 0x03, 0xC5, 0xCC }, codeWriter.ToArray());
        }
Example #11
0
        void Encode_R13_with_no_displ()
        {
            var  writer   = new CodeWriterImpl();
            var  encoder  = Encoder.Create(64, writer);
            var  instr    = Instruction.Create(Code.Mov_r64_rm64, Register.RAX, new MemoryOperand(Register.R13));
            uint len      = encoder.Encode(ref instr, 0);
            var  expected = new byte[] { 0x49, 0x8B, 0x45, 0x00 };
            var  actual   = writer.ToArray();

            Assert.Equal(actual.Length, (int)len);
            Assert.Equal(expected, actual);
        }
Example #12
0
        void EncodeRipRelMemOp()
        {
            var  instr      = Instruction.Create(Code.Add_r32_rm32, Register.ECX, new MemoryOperand(Register.RIP, Register.None, 1, 0x1234_5678_9ABC_DEF1, 8, false, Register.None));
            var  codeWriter = new CodeWriterImpl();
            bool b          = BlockEncoder.TryEncode(64, new InstructionBlock(codeWriter, new[] { instr }, 0x1234_5678_ABCD_EF02), out var errorMessage, out _);

            Assert.True(b, $"Couldn't encode it: {errorMessage}");
            var encoded  = codeWriter.ToArray();
            var expected = new byte[] { 0x03, 0x0D, 0xE9, 0xEF, 0xEE, 0xEE };

            Assert.Equal(expected, encoded);
        }
Example #13
0
        void Encode_EBP_with_no_displ()
        {
            var  writer      = new CodeWriterImpl();
            var  encoder     = Encoder.Create(32, writer);
            var  instruction = Instruction.Create(Code.Mov_r32_rm32, Register.EAX, new MemoryOperand(Register.EBP));
            uint len         = encoder.Encode(instruction, 0);
            var  expected    = new byte[] { 0x8B, 0x45, 0x00 };
            var  actual      = writer.ToArray();

            Assert.Equal(actual.Length, (int)len);
            Assert.Equal(expected, actual);
        }
Example #14
0
        void Encode_MOV_CR8_in_64bit_mode_does_not_add_LOCK(string hexBytes, Code code, string encodedBytes)
        {
            var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes));

            decoder.Decode(out var instr);
            Assert.Equal(code, instr.Code);
            var writer  = new CodeWriterImpl();
            var encoder = decoder.CreateEncoder(writer);

            encoder.Encode(ref instr, 0);
            var expectedBytes = HexUtils.ToByteArray(encodedBytes);
            var actualBytes   = writer.ToArray();

            Assert.Equal(expectedBytes, actualBytes);
        }
Example #15
0
        void Encode_zero_instructions()
        {
            string errorMessage;
            var    codeWriter = new CodeWriterImpl();

            errorMessage = BlockEncoder.Encode(16, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0, Array.Empty <RelocInfo>(), Array.Empty <uint>(), Array.Empty <ConstantOffsets>()), BlockEncoderOptions.None);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());

            errorMessage = BlockEncoder.Encode(32, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0, Array.Empty <RelocInfo>(), Array.Empty <uint>(), Array.Empty <ConstantOffsets>()), BlockEncoderOptions.None);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());

            errorMessage = BlockEncoder.Encode(64, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0, Array.Empty <RelocInfo>(), Array.Empty <uint>(), Array.Empty <ConstantOffsets>()), BlockEncoderOptions.None);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());
        }
Example #16
0
        void Prevent_VEX2_encoding(string hexBytes, string expectedBytes, Code code, bool preventVEX2)
        {
            var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes));

            decoder.IP = DecoderConstants.DEFAULT_IP64;
            decoder.Decode(out var instr);
            Assert.Equal(code, instr.Code);
            var codeWriter = new CodeWriterImpl();
            var encoder    = decoder.CreateEncoder(codeWriter);

            encoder.PreventVEX2 = preventVEX2;
            encoder.Encode(ref instr, DecoderConstants.DEFAULT_IP64);
            var encodedBytes       = codeWriter.ToArray();
            var expectedBytesArray = HexUtils.ToByteArray(expectedBytes);

            Assert.Equal(expectedBytesArray, encodedBytes);
        }
Example #17
0
        void Test_EVEX_WIG_LIG(string hexBytes, string expectedBytes, Code code, uint wig, uint lig)
        {
            var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes));

            decoder.IP = DecoderConstants.DEFAULT_IP64;
            decoder.Decode(out var instruction);
            Assert.Equal(code, instruction.Code);
            var codeWriter = new CodeWriterImpl();
            var encoder    = Encoder.Create(decoder.Bitness, codeWriter);

            encoder.EVEX_WIG = wig;
            encoder.EVEX_LIG = lig;
            encoder.Encode(instruction, DecoderConstants.DEFAULT_IP64);
            var encodedBytes       = codeWriter.ToArray();
            var expectedBytesArray = HexUtils.ToByteArray(expectedBytes);

            Assert.Equal(expectedBytesArray, encodedBytes);
        }
Example #18
0
        void DefaultArgs()
        {
            const int   bitness = 64;
            const ulong origRip = 0x123456789ABCDE00;
            const ulong newRip  = 0x8000000000000000;

            var originalData = new byte[] {
                /*0000*/ 0xB0, 0x00,                   // mov al,0
                /*0002*/ 0xEB, 0x09,                   // jmp short 123456789ABCDE0Dh
                /*0004*/ 0xB0, 0x01,                   // mov al,1
                /*0006*/ 0xE9, 0x03, 0x00, 0x00, 0x00, // jmp near ptr 123456789ABCDE0Eh
                /*000B*/ 0xB0, 0x02,                   // mov al,2
            };
            var instructions = BlockEncoderTest.Decode(bitness, origRip, originalData, DecoderOptions.None);
            var codeWriter   = new CodeWriterImpl();
            var errorMessage = BlockEncoder.Encode(bitness, new InstructionBlock(codeWriter, instructions, newRip));

            Assert.Null(errorMessage);
            Assert.Equal(0x28, codeWriter.ToArray().Length);
        }
Example #19
0
        void Encode_zero_instructions()
        {
            bool               b;
            string             errorMessage;
            BlockEncoderResult result;
            var codeWriter = new CodeWriterImpl();

            b = BlockEncoder.TryEncode(16, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0), out errorMessage, out result, BlockEncoderOptions.None);
            Assert.True(b);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());
            Assert.Equal(0UL, result.RIP);
            Assert.Null(result.RelocInfos);
            Assert.NotNull(result.NewInstructionOffsets);
            Assert.True(result.NewInstructionOffsets.Length == 0);
            Assert.NotNull(result.ConstantOffsets);
            Assert.True(result.ConstantOffsets.Length == 0);

            b = BlockEncoder.TryEncode(32, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0), out errorMessage, out result, BlockEncoderOptions.None);
            Assert.True(b);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());
            Assert.Equal(0UL, result.RIP);
            Assert.Null(result.RelocInfos);
            Assert.NotNull(result.NewInstructionOffsets);
            Assert.True(result.NewInstructionOffsets.Length == 0);
            Assert.NotNull(result.ConstantOffsets);
            Assert.True(result.ConstantOffsets.Length == 0);

            b = BlockEncoder.TryEncode(64, new InstructionBlock(codeWriter, Array.Empty <Instruction>(), 0), out errorMessage, out result, BlockEncoderOptions.None);
            Assert.True(b);
            Assert.Null(errorMessage);
            Assert.Empty(codeWriter.ToArray());
            Assert.Equal(0UL, result.RIP);
            Assert.Null(result.RelocInfos);
            Assert.NotNull(result.NewInstructionOffsets);
            Assert.True(result.NewInstructionOffsets.Length == 0);
            Assert.NotNull(result.ConstantOffsets);
            Assert.True(result.ConstantOffsets.Length == 0);
        }
Example #20
0
        void VerifyResultArrays(BlockEncoderOptions options)
        {
            const int   bitness  = 64;
            const ulong origRip1 = 0x123456789ABCDE00;
            const ulong origRip2 = 0x223456789ABCDE00;
            const ulong newRip1  = 0x8000000000000000;
            const ulong newRip2  = 0x9000000000000000;

            {
                var  instructions1 = BlockEncoderTest.Decode(bitness, origRip1, new byte[] { 0xE9, 0x56, 0x78, 0xA5, 0x5A }, DecoderOptions.None);
                var  codeWriter1   = new CodeWriterImpl();
                bool b             = BlockEncoder.TryEncode(bitness, new InstructionBlock(codeWriter1, instructions1, newRip1), out var errorMessage, out var result, options);
                Assert.True(b);
                Assert.Null(errorMessage);
                Assert.Equal(newRip1, result.RIP);
                if ((options & BlockEncoderOptions.ReturnRelocInfos) != 0)
                {
                    Assert.NotNull(result.RelocInfos);
                    Assert.True(result.RelocInfos.Count == 1);
                }
                else
                {
                    Assert.Null(result.RelocInfos);
                }
                if ((options & BlockEncoderOptions.ReturnNewInstructionOffsets) != 0)
                {
                    Assert.NotNull(result.NewInstructionOffsets);
                    Assert.True(result.NewInstructionOffsets.Length == 1);
                }
                else
                {
                    Assert.NotNull(result.NewInstructionOffsets);
                    Assert.True(result.NewInstructionOffsets.Length == 0);
                }
                if ((options & BlockEncoderOptions.ReturnConstantOffsets) != 0)
                {
                    Assert.NotNull(result.ConstantOffsets);
                    Assert.True(result.ConstantOffsets.Length == 1);
                }
                else
                {
                    Assert.NotNull(result.ConstantOffsets);
                    Assert.True(result.ConstantOffsets.Length == 0);
                }
            }
            {
                var  instructions1 = BlockEncoderTest.Decode(bitness, origRip1, new byte[] { 0xE9, 0x56, 0x78, 0xA5, 0x5A }, DecoderOptions.None);
                var  instructions2 = BlockEncoderTest.Decode(bitness, origRip2, new byte[] { 0x90, 0xE9, 0x56, 0x78, 0xA5, 0x5A }, DecoderOptions.None);
                var  codeWriter1   = new CodeWriterImpl();
                var  codeWriter2   = new CodeWriterImpl();
                var  block1        = new InstructionBlock(codeWriter1, instructions1, newRip1);
                var  block2        = new InstructionBlock(codeWriter2, instructions2, newRip2);
                bool b             = BlockEncoder.TryEncode(bitness, new[] { block1, block2 }, out var errorMessage, out var resultArray, options);
                Assert.True(b);
                Assert.Null(errorMessage);
                Assert.NotNull(resultArray);
                Assert.Equal(2, resultArray.Length);
                Assert.Equal(newRip1, resultArray[0].RIP);
                Assert.Equal(newRip2, resultArray[1].RIP);
                if ((options & BlockEncoderOptions.ReturnRelocInfos) != 0)
                {
                    Assert.NotNull(resultArray[0].RelocInfos);
                    Assert.NotNull(resultArray[1].RelocInfos);
                    Assert.True(resultArray[0].RelocInfos.Count == 1);
                    Assert.True(resultArray[1].RelocInfos.Count == 1);
                }
                else
                {
                    Assert.Null(resultArray[0].RelocInfos);
                    Assert.Null(resultArray[1].RelocInfos);
                }
                if ((options & BlockEncoderOptions.ReturnNewInstructionOffsets) != 0)
                {
                    Assert.NotNull(resultArray[0].NewInstructionOffsets);
                    Assert.NotNull(resultArray[1].NewInstructionOffsets);
                    Assert.True(resultArray[0].NewInstructionOffsets.Length == 1);
                    Assert.True(resultArray[1].NewInstructionOffsets.Length == 2);
                }
                else
                {
                    Assert.NotNull(resultArray[0].NewInstructionOffsets);
                    Assert.True(resultArray[0].NewInstructionOffsets.Length == 0);
                    Assert.NotNull(resultArray[1].NewInstructionOffsets);
                    Assert.True(resultArray[1].NewInstructionOffsets.Length == 0);
                }
                if ((options & BlockEncoderOptions.ReturnConstantOffsets) != 0)
                {
                    Assert.NotNull(resultArray[0].ConstantOffsets);
                    Assert.NotNull(resultArray[1].ConstantOffsets);
                    Assert.True(resultArray[0].ConstantOffsets.Length == 1);
                    Assert.True(resultArray[1].ConstantOffsets.Length == 2);
                }
                else
                {
                    Assert.NotNull(resultArray[0].ConstantOffsets);
                    Assert.True(resultArray[0].ConstantOffsets.Length == 0);
                    Assert.NotNull(resultArray[1].ConstantOffsets);
                    Assert.True(resultArray[1].ConstantOffsets.Length == 0);
                }
            }
        }