Пример #1
0
 public override int GetHashCode()
 => MemoryMarshal.Read <int> (Hash.Span);
Пример #2
0
 public static T SpanToStructureLittleEndian <T>(ReadOnlySpan <byte> bytes) where T : struct =>
 MemoryMarshal.Read <T>(bytes);
Пример #3
0
 public override int GetHashCode()
 {
     return(MemoryMarshal.Read <int>(Bytes));
 }
Пример #4
0
        public void ConstantSizeArray()
        {
            var longVal = 0x12345678ABCDEF10L;

            Assert.Equal(longVal, MemoryMarshal.Read <long>(NativeExportsNE.Arrays.GetLongBytes(longVal)));
        }
        public static IEnumerable <FunctionExport> ReadFunctionExports(this PEImage file)
        {
            var exports = file.OptionalHeader.ExportDirectory;

            if (exports.Size == 0)
            {
                yield break;
            }

            var buffer = new byte[exports.Size];

            file.Read(buffer, exports.VirtualAddress, exports.Size);

            var exp = MemoryMarshal.Read <IMAGE_EXPORT_DIRECTORY>(buffer);

            var reader = new BinaryReader(file.Stream);

            var nameAddresses = new List <int>();
            var names         = new List <string>();

            reader.BaseStream.Seek(file.RvaToOffset((int)exp.AddressOfNames), SeekOrigin.Begin);

            for (int i = 0; i < exp.NumberOfNames; i++)
            {
                nameAddresses.Add(reader.ReadInt32());
            }

            foreach (var address in nameAddresses)
            {
                reader.BaseStream.Seek(file.RvaToOffset(address), SeekOrigin.Begin);

                names.Add(reader.ReadRawString());
            }

            var ordinals = new List <int>();

            reader.BaseStream.Seek(file.RvaToOffset((int)exp.AddressOfNameOrdinals), SeekOrigin.Begin);

            for (int i = 0; i < exp.NumberOfNames; i++)
            {
                ordinals.Add(reader.ReadInt16());
            }

            var addresses = new List <int>();

            reader.BaseStream.Seek(file.RvaToOffset((int)exp.AddressOfFunctions), SeekOrigin.Begin);

            for (int i = 0; i < exp.NumberOfFunctions; i++)
            {
                var address = reader.ReadInt32();

                int indexOfOrdinal = -1;

                for (int j = 0; j < ordinals.Count; j++)
                {
                    if (ordinals[j] == i)
                    {
                        indexOfOrdinal = j;
                    }
                }

                yield return(new FunctionExport(names[indexOfOrdinal], address));
            }
        }
Пример #6
0
        public int ReadInt24(long offset, bool updatePosition)
        {
            FillBuffer(offset, 3, updatePosition);

            return(BitTools.SignExtend32(MemoryMarshal.Read <int>(_buffer), 24));
        }
Пример #7
0
        public ulong ReadUInt64(long offset, bool updatePosition)
        {
            FillBuffer(offset, sizeof(ulong), updatePosition);

            return(MemoryMarshal.Read <ulong>(_buffer));
        }
Пример #8
0
 internal static T ReadStruct <T>(this Process process, IntPtr address) where T : unmanaged
 {
     return(MemoryMarshal.Read <T>(process.ReadSpan <byte>(address, Unsafe.SizeOf <T>())));
 }
Пример #9
0
        private IEnumerable <int> ReadTlsCallbackOffsets()
        {
            // Calculate offset of the TLS table

            if (!PeHeaders.TryGetDirectoryOffset(PeHeaders.PEHeader.ThreadLocalStorageTableDirectory, out var tlsTableOffset))
            {
                yield break;
            }

            if (PeHeaders.PEHeader.Magic == PEMagic.PE32)
            {
                // Calculate the offset of the TLS callbacks

                var tlsTable = MemoryMarshal.Read <ImageTlsDirectory32>(PeBytes.Slice(tlsTableOffset).Span);

                if (tlsTable.AddressOfCallbacks == 0)
                {
                    yield break;
                }

                var tlsCallbacksOffset = RvaToOffset(tlsTable.AddressOfCallbacks - (int)PeHeaders.PEHeader.ImageBase);

                // Read the offsets of the TLS callbacks

                for (var tlsCallbackIndex = 0;; tlsCallbackIndex++)
                {
                    var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(int) * tlsCallbackIndex;

                    var tlsCallbackVa = MemoryMarshal.Read <int>(PeBytes.Slice(tlsCallbackVaOffset).Span);

                    if (tlsCallbackVa == 0)
                    {
                        break;
                    }

                    yield return(tlsCallbackVa - (int)PeHeaders.PEHeader.ImageBase);
                }
            }

            else
            {
                // Calculate the offset of the TLS callbacks

                var tlsTable = MemoryMarshal.Read <ImageTlsDirectory64>(PeBytes.Slice(tlsTableOffset).Span);

                if (tlsTable.AddressOfCallbacks == 0)
                {
                    yield break;
                }

                var tlsCallbacksOffset = RvaToOffset((int)(tlsTable.AddressOfCallbacks - (long)PeHeaders.PEHeader.ImageBase));

                // Read the offsets of the TLS callbacks

                for (var tlsCallbackIndex = 0;; tlsCallbackIndex++)
                {
                    var tlsCallbackVaOffset = tlsCallbacksOffset + sizeof(long) * tlsCallbackIndex;

                    var tlsCallbackVa = MemoryMarshal.Read <long>(PeBytes.Slice(tlsCallbackVaOffset).Span);

                    if (tlsCallbackVa == 0)
                    {
                        break;
                    }

                    yield return((int)(tlsCallbackVa - (long)PeHeaders.PEHeader.ImageBase));
                }
            }
        }
Пример #10
0
 /// <summary>
 ///     Cast all entries to the specified struct type.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public List <T> Cast <T>() where T : struct => Entries.Select(x => MemoryMarshal.Read <T>(x.Span)).ToList();
Пример #11
0
        private IEnumerable <ImportedFunction> ReadImportedFunctions(int currentIatOffset, int currentThunkOffset)
        {
            while (true)
            {
                int functionDataOffset;

                if (Headers.PEHeader.Magic == PEMagic.PE32)
                {
                    // Read the thunk of the function

                    var functionThunk = MemoryMarshal.Read <int>(ImageBuffer.Span.Slice(currentThunkOffset));

                    if (functionThunk == 0)
                    {
                        break;
                    }

                    // Check if the function is imported via ordinal

                    if ((functionThunk & int.MinValue) != 0)
                    {
                        yield return(new ImportedFunction(currentIatOffset, null, functionThunk & ushort.MaxValue));

                        continue;
                    }

                    functionDataOffset = RvaToOffset(functionThunk);
                }

                else
                {
                    // Read the thunk of the function

                    var functionThunk = MemoryMarshal.Read <long>(ImageBuffer.Span.Slice(currentThunkOffset));

                    if (functionThunk == 0)
                    {
                        break;
                    }

                    // Check if the function is imported via ordinal

                    if ((functionThunk & long.MinValue) != 0)
                    {
                        yield return(new ImportedFunction(currentIatOffset, null, (int)functionThunk & ushort.MaxValue));

                        continue;
                    }

                    functionDataOffset = RvaToOffset((int)functionThunk);
                }

                // Read the name of the function

                var functionNameOffset = functionDataOffset + sizeof(short);

                var functionName = ReadString(functionNameOffset);

                // Read the ordinal of the imported function

                var functionOrdinal = MemoryMarshal.Read <short>(ImageBuffer.Span.Slice(functionDataOffset));

                yield return(new ImportedFunction(currentIatOffset, functionName, functionOrdinal));

                // Set the offset of the next function IAT and thunk offset

                if (Headers.PEHeader.Magic == PEMagic.PE32)
                {
                    currentIatOffset += sizeof(int);

                    currentThunkOffset += sizeof(int);
                }

                else
                {
                    currentIatOffset += sizeof(long);

                    currentThunkOffset += sizeof(long);
                }
            }
        }
Пример #12
0
        public KeyValuePair <uint, uint> GetStorageSizeOfCurrentKey()
        {
            if (!IsValidKey())
            {
                return(new KeyValuePair <uint, uint>());
            }
            var keyLen    = _cursor.GetKeyLength();
            var trueValue = _cursor.GetValue();

            return(new KeyValuePair <uint, uint>(
                       (uint)keyLen,
                       _keyValueDB.CalcValueSize(MemoryMarshal.Read <uint>(trueValue), MemoryMarshal.Read <uint>(trueValue.Slice(4)), MemoryMarshal.Read <int>(trueValue.Slice(8)))));
        }
Пример #13
0
        public void ConstantSizeCollection()
        {
            var longVal = 0x12345678ABCDEF10L;

            Assert.Equal(longVal, MemoryMarshal.Read <long>(CollectionsMarshal.AsSpan(NativeExportsNE.Collections.GetLongBytes(longVal))));
        }
Пример #14
0
        public static Guid ReadGuid(this Span <byte> span, int offset)
        {
            var guidSpan = span.Slice(offset, 16);

            return(MemoryMarshal.Read <Guid>(guidSpan));
        }
Пример #15
0
        public short ReadInt16(long offset, bool updatePosition)
        {
            FillBuffer(offset, sizeof(short), updatePosition);

            return(MemoryMarshal.Read <short>(_buffer));
        }
Пример #16
0
 private static ushort ReadLowerCaseUInt16(ReadOnlySpan <byte> value)
 => (ushort)(MemoryMarshal.Read <ushort>(value) | 0x0020);
Пример #17
0
        public int ReadUInt24(long offset, bool updatePosition)
        {
            FillBuffer(offset, 3, updatePosition);

            return(MemoryMarshal.Read <int>(_buffer) & 0xFFFFFF);
        }
Пример #18
0
        /// <summary>
        /// Read a <see cref="Request.EvaluationResult"/> request
        /// </summary>
        /// <param name="from">Origin</param>
        /// <param name="expression">Expression</param>
        /// <param name="result">Evaluation result</param>
        /// <returns>Number of bytes read</returns>
        public static int ReadEvaluationResult(ReadOnlySpan <byte> from, out string expression, out object result)
        {
            EvaluationResultHeader header = MemoryMarshal.Cast <byte, EvaluationResultHeader>(from)[0];
            int bytesRead = Marshal.SizeOf(header);

            // Read expression
            ReadOnlySpan <byte> unicodeExpression = from.Slice(bytesRead, header.ExpressionLength);

            expression = Encoding.UTF8.GetString(unicodeExpression);
            bytesRead += header.ExpressionLength;

            // Read value
            switch (header.Type)
            {
            case DataType.Int:
                result = header.IntValue;
                break;

            case DataType.UInt:
                result = header.UIntValue;
                break;

            case DataType.Float:
                result = header.FloatValue;
                break;

            case DataType.IntArray:
                int[] intArray = new int[header.IntValue];
                for (int i = 0; i < header.IntValue; i++)
                {
                    intArray[i] = MemoryMarshal.Read <int>(from.Slice(bytesRead));
                    bytesRead  += Marshal.SizeOf <int>();
                }
                result = intArray;
                break;

            case DataType.UIntArray:
                uint[] uintArray = new uint[header.IntValue];
                for (int i = 0; i < header.IntValue; i++)
                {
                    uintArray[i] = MemoryMarshal.Read <uint>(from.Slice(bytesRead));
                    bytesRead   += Marshal.SizeOf <uint>();
                }
                result = uintArray;
                break;

            case DataType.FloatArray:
                float[] floatArray = new float[header.IntValue];
                for (int i = 0; i < header.IntValue; i++)
                {
                    floatArray[i] = MemoryMarshal.Read <float>(from.Slice(bytesRead));
                    bytesRead    += Marshal.SizeOf <float>();
                }
                result = floatArray;
                break;

            case DataType.String:
                result     = Encoding.UTF8.GetString(from.Slice(bytesRead, header.IntValue));
                bytesRead += header.IntValue;
                break;

            case DataType.DriverId:
                result = new DriverId(header.UIntValue);
                break;

            case DataType.DriverIdArray:
                DriverId[] driverIdArray = new DriverId[header.IntValue];
                for (int i = 0; i < header.IntValue; i++)
                {
                    driverIdArray[i] = new DriverId(MemoryMarshal.Read <uint>(from.Slice(bytesRead)));
                    bytesRead       += Marshal.SizeOf <uint>();
                }
                result = driverIdArray;
                break;

            case DataType.Bool:
                result = Convert.ToBoolean(header.IntValue);
                break;

            case DataType.BoolArray:
                bool[] boolArray = new bool[header.IntValue];
                for (int i = 0; i < header.IntValue; i++)
                {
                    boolArray[i] = Convert.ToBoolean(MemoryMarshal.Read <byte>(from.Slice(bytesRead)));
                    bytesRead   += Marshal.SizeOf <byte>();
                }
                result = boolArray;
                break;

            case DataType.Expression:
                string errorMessage = Encoding.UTF8.GetString(from.Slice(bytesRead, header.IntValue));
                result = new CodeParserException(errorMessage);
                break;

            default:
                result = null;
                break;
            }

            return(AddPadding(bytesRead));
        }
Пример #19
0
        public int ReadInt32(long offset, bool updatePosition)
        {
            FillBuffer(offset, sizeof(int), updatePosition);

            return(MemoryMarshal.Read <int>(_buffer));
        }
Пример #20
0
 public static unsafe float ReadSingleBigEndian(ReadOnlySpan <byte> source)
 {
     return(BitConverter.IsLittleEndian ?
            Int32BitsToSingle(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read <int>(source))) :
            MemoryMarshal.Read <float>(source));
 }
Пример #21
0
 /// <summary>
 /// Reads the header.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <returns></returns>
 public T ReadHeader <T>() where T : struct
 {
     return(MemoryMarshal.Read <T>(_memory.Span));
 }
Пример #22
0
 public static double ReadDoubleBigEndian(ReadOnlySpan <byte> source)
 {
     return(BitConverter.IsLittleEndian ?
            BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(MemoryMarshal.Read <long>(source))) :
            MemoryMarshal.Read <double>(source));
 }
Пример #23
0
        /// <summary>
        /// Given the metadata for an event and an event payload, decode and deserialize the event payload.
        /// </summary>
        internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, ReadOnlySpan <byte> payload)
        {
            ParameterInfo[] parameters    = metadata.Parameters;
            object[]        decodedFields = new object[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                // It is possible that an older version of the event was emitted.
                // If this happens, the payload might be missing arguments at the end.
                // We can just leave these unset.
                if (payload.Length <= 0)
                {
                    break;
                }

                Type parameterType = parameters[i].ParameterType;
                if (parameterType == typeof(IntPtr))
                {
                    if (IntPtr.Size == 8)
                    {
                        decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt64LittleEndian(payload);
                    }
                    else
                    {
                        decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt32LittleEndian(payload);
                    }
                    payload = payload.Slice(IntPtr.Size);
                }
                else if (parameterType == typeof(int))
                {
                    decodedFields[i] = BinaryPrimitives.ReadInt32LittleEndian(payload);
                    payload          = payload.Slice(sizeof(int));
                }
                else if (parameterType == typeof(uint))
                {
                    decodedFields[i] = BinaryPrimitives.ReadUInt32LittleEndian(payload);
                    payload          = payload.Slice(sizeof(uint));
                }
                else if (parameterType == typeof(long))
                {
                    decodedFields[i] = BinaryPrimitives.ReadInt64LittleEndian(payload);
                    payload          = payload.Slice(sizeof(long));
                }
                else if (parameterType == typeof(ulong))
                {
                    decodedFields[i] = BinaryPrimitives.ReadUInt64LittleEndian(payload);
                    payload          = payload.Slice(sizeof(ulong));
                }
                else if (parameterType == typeof(byte))
                {
                    decodedFields[i] = MemoryMarshal.Read <byte>(payload);
                    payload          = payload.Slice(sizeof(byte));
                }
                else if (parameterType == typeof(sbyte))
                {
                    decodedFields[i] = MemoryMarshal.Read <sbyte>(payload);
                    payload          = payload.Slice(sizeof(sbyte));
                }
                else if (parameterType == typeof(short))
                {
                    decodedFields[i] = BinaryPrimitives.ReadInt16LittleEndian(payload);
                    payload          = payload.Slice(sizeof(short));
                }
                else if (parameterType == typeof(ushort))
                {
                    decodedFields[i] = BinaryPrimitives.ReadUInt16LittleEndian(payload);
                    payload          = payload.Slice(sizeof(ushort));
                }
                else if (parameterType == typeof(float))
                {
                    decodedFields[i] = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(payload));
                    payload          = payload.Slice(sizeof(float));
                }
                else if (parameterType == typeof(double))
                {
                    decodedFields[i] = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(payload));
                    payload          = payload.Slice(sizeof(double));
                }
                else if (parameterType == typeof(bool))
                {
                    // The manifest defines a bool as a 32bit type (WIN32 BOOL), not 1 bit as CLR Does.
                    decodedFields[i] = (BinaryPrimitives.ReadInt32LittleEndian(payload) == 1);
                    payload          = payload.Slice(sizeof(int));
                }
                else if (parameterType == typeof(Guid))
                {
                    const int sizeOfGuid = 16;
                    decodedFields[i] = new Guid(payload.Slice(0, sizeOfGuid));
                    payload          = payload.Slice(sizeOfGuid);
                }
                else if (parameterType == typeof(char))
                {
                    decodedFields[i] = (char)BinaryPrimitives.ReadUInt16LittleEndian(payload);
                    payload          = payload.Slice(sizeof(char));
                }
                else if (parameterType == typeof(string))
                {
                    // Try to find null terminator (0x00) from the byte span
                    // NOTE: we do this by hand instead of using IndexOf because payload may be unaligned due to
                    // mixture of different types being stored in the same buffer. (see eventpipe.cpp:CopyData)
                    int byteCount = -1;
                    for (int j = 1; j < payload.Length; j += 2)
                    {
                        if (payload[j - 1] == (byte)(0) && payload[j] == (byte)(0))
                        {
                            byteCount = j + 1;
                            break;
                        }
                    }

                    ReadOnlySpan <char> charPayload;
                    if (byteCount < 0)
                    {
                        charPayload = MemoryMarshal.Cast <byte, char>(payload);
                        payload     = default;
                    }
                    else
                    {
                        charPayload = MemoryMarshal.Cast <byte, char>(payload.Slice(0, byteCount - 2));
                        payload     = payload.Slice(byteCount);
                    }
                    decodedFields[i] = BitConverter.IsLittleEndian ? new string(charPayload) : Encoding.Unicode.GetString(MemoryMarshal.Cast <char, byte>(charPayload));
                }
                else
                {
                    Debug.Fail("Unsupported type encountered.");
                }
            }

            return(decodedFields);
        }
Пример #24
0
 /// <summary>
 ///     Initialize with buffer
 /// </summary>
 /// <param name="buffer"></param>
 public WaveBankData(Span <byte> buffer)
 {
     Header = MemoryMarshal.Read <ResourceSectionHeader>(buffer);
     Data   = new Memory <byte>(buffer.Slice(SizeHelper.SizeOf <ResourceSectionHeader>()).ToArray());
 }
Пример #25
0
        /// <summary>
        /// Reads a structure from the current stream position.
        /// </summary>
        /// <param name="br"></param>
        /// <typeparam name="T">The structure to read in to</typeparam>
        /// <returns>The file data as a structure</returns>
        public static T ReadStructure <T>(this BinaryReader br) where T : struct
        {
            ReadOnlySpan <byte> data = br.ReadBytes(Unsafe.SizeOf <T>());

            return(MemoryMarshal.Read <T>(data));
        }
Пример #26
0
        public float ReadSingle(long offset, bool updatePosition)
        {
            FillBuffer(offset, sizeof(float), updatePosition);

            return(MemoryMarshal.Read <float>(_buffer));
        }
Пример #27
0
 public static T SpanToStructureLittleEndian <T>(ReadOnlySpan <byte> bytes, int start, int length)
     where T : struct => MemoryMarshal.Read <T>(bytes.Slice(start, length));
Пример #28
0
        public double ReadDouble(long offset, bool updatePosition)
        {
            FillBuffer(offset, sizeof(double), updatePosition);

            return(MemoryMarshal.Read <double>(_buffer));
        }
Пример #29
0
        public void ReadOnlySpanRead()
        {
            ulong value; // [11 22 33 44 55 66 77 88]

            if (BitConverter.IsLittleEndian)
            {
                value = 0x8877665544332211;
            }
            else
            {
                value = 0x1122334455667788;
            }
            ReadOnlySpan <byte> span;

            unsafe
            {
                span = new ReadOnlySpan <byte>(&value, 8);
            }

            Assert.Equal <byte>(0x11, MemoryMarshal.Read <byte>(span));
            Assert.True(MemoryMarshal.TryRead(span, out byte byteValue));
            Assert.Equal(0x11, byteValue);

            Assert.Equal <sbyte>(0x11, MemoryMarshal.Read <sbyte>(span));
            Assert.True(MemoryMarshal.TryRead(span, out byte sbyteValue));
            Assert.Equal(0x11, byteValue);

            Assert.Equal <ushort>(0x1122, ReadUInt16BigEndian(span));
            Assert.True(TryReadUInt16BigEndian(span, out ushort ushortValue));
            Assert.Equal(0x1122, ushortValue);

            Assert.Equal <ushort>(0x2211, ReadUInt16LittleEndian(span));
            Assert.True(TryReadUInt16LittleEndian(span, out ushortValue));
            Assert.Equal(0x2211, ushortValue);

            Assert.Equal <short>(0x1122, ReadInt16BigEndian(span));
            Assert.True(TryReadInt16BigEndian(span, out short shortValue));
            Assert.Equal(0x1122, shortValue);

            Assert.Equal <short>(0x2211, ReadInt16LittleEndian(span));
            Assert.True(TryReadInt16LittleEndian(span, out shortValue));
            Assert.Equal(0x2211, ushortValue);

            Assert.Equal <uint>(0x11223344, ReadUInt32BigEndian(span));
            Assert.True(TryReadUInt32BigEndian(span, out uint uintValue));
            Assert.Equal <uint>(0x11223344, uintValue);

            Assert.Equal <uint>(0x44332211, ReadUInt32LittleEndian(span));
            Assert.True(TryReadUInt32LittleEndian(span, out uintValue));
            Assert.Equal <uint>(0x44332211, uintValue);

            Assert.Equal <int>(0x11223344, ReadInt32BigEndian(span));
            Assert.True(TryReadInt32BigEndian(span, out int intValue));
            Assert.Equal <int>(0x11223344, intValue);

            Assert.Equal <int>(0x44332211, ReadInt32LittleEndian(span));
            Assert.True(TryReadInt32LittleEndian(span, out intValue));
            Assert.Equal <int>(0x44332211, intValue);

            Assert.Equal <ulong>(0x1122334455667788, ReadUInt64BigEndian(span));
            Assert.True(TryReadUInt64BigEndian(span, out ulong ulongValue));
            Assert.Equal <ulong>(0x1122334455667788, ulongValue);

            Assert.Equal <ulong>(0x8877665544332211, ReadUInt64LittleEndian(span));
            Assert.True(TryReadUInt64LittleEndian(span, out ulongValue));
            Assert.Equal <ulong>(0x8877665544332211, ulongValue);

            Assert.Equal <long>(0x1122334455667788, ReadInt64BigEndian(span));
            Assert.True(TryReadInt64BigEndian(span, out long longValue));
            Assert.Equal <long>(0x1122334455667788, longValue);

            Assert.Equal <long>(unchecked ((long)0x8877665544332211), ReadInt64LittleEndian(span));
            Assert.True(TryReadInt64LittleEndian(span, out longValue));
            Assert.Equal <long>(unchecked ((long)0x8877665544332211), longValue);

            Half expectedHalf = BitConverter.Int16BitsToHalf(0x1122);

            Assert.Equal <Half>(expectedHalf, ReadHalfBigEndian(span));
            Assert.True(TryReadHalfBigEndian(span, out Half halfValue));
            Assert.Equal <Half>(expectedHalf, halfValue);

            expectedHalf = BitConverter.Int16BitsToHalf(0x2211);
            Assert.Equal <Half>(expectedHalf, ReadHalfLittleEndian(span));
            Assert.True(TryReadHalfLittleEndian(span, out halfValue));
            Assert.Equal <Half>(expectedHalf, halfValue);

            float expectedFloat = BitConverter.Int32BitsToSingle(0x11223344);

            Assert.Equal <float>(expectedFloat, ReadSingleBigEndian(span));
            Assert.True(TryReadSingleBigEndian(span, out float floatValue));
            Assert.Equal <float>(expectedFloat, floatValue);

            expectedFloat = BitConverter.Int32BitsToSingle(0x44332211);
            Assert.Equal <float>(expectedFloat, ReadSingleLittleEndian(span));
            Assert.True(TryReadSingleLittleEndian(span, out floatValue));
            Assert.Equal <float>(expectedFloat, floatValue);

            double expectedDouble = BitConverter.Int64BitsToDouble(0x1122334455667788);

            Assert.Equal <double>(expectedDouble, ReadDoubleBigEndian(span));
            Assert.True(TryReadDoubleBigEndian(span, out double doubleValue));
            Assert.Equal <double>(expectedDouble, doubleValue);

            expectedDouble = BitConverter.Int64BitsToDouble(unchecked ((long)0x8877665544332211));
            Assert.Equal <double>(expectedDouble, ReadDoubleLittleEndian(span));
            Assert.True(TryReadDoubleLittleEndian(span, out doubleValue));
            Assert.Equal <double>(expectedDouble, doubleValue);
        }
Пример #30
0
        private IEnumerable <ImportedFunction> ReadImportedFunctions(int descriptorThunkOffset, int importAddressTableOffset)
        {
            for (var functionIndex = 0;; functionIndex++)
            {
                int functionOffset;

                int functionDataOffset;

                if (PeHeaders.PEHeader.Magic == PEMagic.PE32)
                {
                    // Read the thunk data of the function

                    var functionThunkDataOffset = descriptorThunkOffset + sizeof(int) * functionIndex;

                    var functionThunkData = MemoryMarshal.Read <int>(PeBytes.Slice(functionThunkDataOffset).Span);

                    if (functionThunkData == 0)
                    {
                        break;
                    }

                    // Calculate the offset of the function

                    functionOffset = importAddressTableOffset + sizeof(int) * functionIndex;

                    // Determine if the function is imported via ordinal

                    if ((functionThunkData & int.MinValue) != 0)
                    {
                        yield return(new ImportedFunction(null, functionOffset, functionThunkData & ushort.MaxValue));

                        continue;
                    }

                    functionDataOffset = RvaToOffset(functionThunkData);
                }

                else
                {
                    // Read the thunk data of the function

                    var functionThunkDataOffset = descriptorThunkOffset + sizeof(long) * functionIndex;

                    var functionThunkData = MemoryMarshal.Read <long>(PeBytes.Slice(functionThunkDataOffset).Span);

                    if (functionThunkData == 0)
                    {
                        break;
                    }

                    // Calculate the offset of the function

                    functionOffset = importAddressTableOffset + sizeof(long) * functionIndex;

                    // Determine if the function is imported via ordinal

                    if ((functionThunkData & long.MinValue) != 0)
                    {
                        yield return(new ImportedFunction(null, functionOffset, (int)functionThunkData & ushort.MaxValue));

                        continue;
                    }

                    functionDataOffset = RvaToOffset((int)functionThunkData);
                }

                // Read the name of the function

                var functionName = ReadNullTerminatedString(functionDataOffset + sizeof(short));

                // Read the ordinal of the function

                var functionOrdinal = MemoryMarshal.Read <short>(PeBytes.Slice(functionDataOffset).Span);

                yield return(new ImportedFunction(functionName, functionOffset, functionOrdinal));
            }
        }