Beispiel #1
0
        /// <summary>
        /// Changes memory permissions to ensure memory can be written and writes a generic type array to a specified memory address.
        /// </summary>
        /// <typeparam name="T">An individual struct type of a class with an explicit StructLayout.LayoutKind attribute.</typeparam>
        /// <param name="memory"></param>
        /// <param name="memoryAddress">The memory address to write to.</param>
        /// <param name="items">The array of items to write to the address.</param>
        /// <param name="marshal">Set this to true to enable struct marshalling.</param>
        public static void SafeWrite <T>(this IMemory memory, IntPtr memoryAddress, T[] items, bool marshal = false)
        {
            int regionSize = StructArray.GetSize <T>(items.Length, marshal);

            var oldProtection = memory.ChangePermission(memoryAddress, regionSize, Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE);

            memory.Write(memoryAddress, items, marshal);
            memory.ChangePermission(memoryAddress, regionSize, oldProtection);
        }
Beispiel #2
0
        /// <summary>
        /// Changes memory permissions to ensure memory can be read and reads a generic type array from a specified memory address.
        /// </summary>
        /// <typeparam name="T">An individual struct type of a class with an explicit StructLayout.LayoutKind attribute.</typeparam>
        /// <param name="memory"></param>
        /// <param name="memoryAddress">The memory address to read from.</param>
        /// <param name="value">Local variable to receive the read in struct array.</param>
        /// <param name="arrayLength">The amount of array items to read.</param>
        /// <param name="marshal">Set this to true to enable struct marshalling.</param>
        public static void SafeRead <T>(this IMemory memory, IntPtr memoryAddress, out T[] value, int arrayLength, bool marshal = false)
        {
            int regionSize = StructArray.GetSize <T>(arrayLength, marshal);

            var oldProtection = memory.ChangePermission(memoryAddress, regionSize, Kernel32.Kernel32.MEM_PROTECTION.PAGE_EXECUTE_READWRITE);

            memory.Read(memoryAddress, out value, arrayLength, marshal);
            memory.ChangePermission(memoryAddress, regionSize, oldProtection);
        }
        /* Construction Helpers */

        private void CopyVertices(ManagedSpline managedSpline)
        {
            var memory   = Memory.Instance;
            var vertices = managedSpline.Vertices;

            int structSize = StructArray.GetSize <SplineVertex>(vertices.Length);

            VertexList = (SplineVertex *)memory.Allocate(structSize);
            StructArray.ToPtr((IntPtr)VertexList, vertices);
        }
Beispiel #4
0
        /// <summary>
        /// Shows some functionality of the <see cref="Struct"/> and <see cref="StructArray"/> utility classes.
        /// </summary>
        /// <param name="memory">This object is used to perform memory read/write/free/allocate operations.</param>
        /// <param name="memoryLocation">Arbitrary location in memory where this tutorial will be held.</param>
        private static void StructUtilityExample(IMemory memory, IntPtr memoryLocation)
        {
            // Under the hood; the IMemory implementations may use a certain struct utility classes known as Struct
            // and StructArray which provide various methods for struct conversions and general work with structs.

            // Like earlier; let's load the adventure binary file.
            byte[] physicsData = File.ReadAllBytes($"phys.bin");

            // But this time; do a direct conversion rather than reading from memory.
            // Note that you don't even need to specify item count this time arounnd.
            // This is auto-decided from array size, but can be manually overwritten.
            StructArray.FromArray(physicsData, out AdventurePhysics[] adventurePhysics);

            // Calculate total array size (in bytes).
            int arraySize = StructArray.GetSize <AdventurePhysics>(adventurePhysics.Length);

            // Get raw bytes for the struct.
            byte[] physicsDataBack = StructArray.GetBytes(adventurePhysics);

            // You can also read/write structures; as a shorthand to Memory class.
            StructArray.ToPtr(memoryLocation, adventurePhysics);
            StructArray.FromPtr(memoryLocation, out AdventurePhysics[] adventurePhysicsCopy, adventurePhysics.Length);

            // Beware of the double sided blade however.
            // A. Struct class allows you to change the source read/write source for FromPtr and ToPtr.
            // B. It affects both Struct and StructArray.

            // Note: There are also explicit overloads for FromPtr and ToPtr that let you use a source without modifying current source.
            Struct.Source = memory; // And of course the source is an implementation of IMemory.

            // Print details.
            if (physicsDataBack.SequenceEqual(physicsDataBack))
            {
                Console.WriteLine($"Success: Original Physics Data and StructArray.GetBytes() are Equal");
            }

            Console.WriteLine($"Struct Array Size: {arraySize}");
        }