Beispiel #1
0
        private void SetupPointers(byte *oneFileStart)
        {
            Header            = (OneArchiveHeader *)oneFileStart;
            NameSectionHeader = (OneNameSectionHeader *)((byte *)Header + sizeof(OneArchiveHeader));
            Names             = new FixedArrayPtr <OneFileName>((ulong)((byte *)NameSectionHeader + sizeof(OneNameSectionHeader)), NameSectionHeader->GetNameCount());
            Files             = (OneFileEntry *)((byte *)Names.Pointer + NameSectionHeader->FileNameSectionLength);

            _fileLength = Header->FileSize + sizeof(OneArchiveHeader);
        }
Beispiel #2
0
        /// <summary>
        /// A simple method example which demonstrates struct Array operations.
        /// </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 StructArrayExample(IMemory memory, IntPtr memoryLocation)
        {
            // Let's load a binary file from the disk and write it to memory.
            const int itemCount = 40; // Number of items in struct array (known).

            byte[] physicsData = File.ReadAllBytes($"phys.bin");
            memory.WriteRaw(memoryLocation, physicsData);

            // Array Read & Write from/to Memory
            memory.Read(memoryLocation, out AdventurePhysics[] adventurePhysicsData, itemCount);
            memory.Write(memoryLocation, adventurePhysicsData);

            // Pointer to array in memory. Provides enhanced functionality over a standard pointer.
            var adventurePhysics = new ArrayPtr <AdventurePhysics>((ulong)memoryLocation);

            adventurePhysics.Get(out AdventurePhysics value, 0);                        // And of course read/writes work..
                                                                                        // Uh? Yeah, for performance the indexer is not overwritten.
            float speedCap = value.HorizontalSpeedCap;

            // Pointer to array in memory with known length. Provides even extra functionality. (Like foreach, LINQ)
            var   adventurePhysicsFixed  = new FixedArrayPtr <AdventurePhysics>((ulong)memoryLocation, itemCount);
            float averageAirAcceleration = adventurePhysicsFixed.Average(physics => physics.AirAcceleration); // LINQ

            // All of these classes support read/writes from arbitrary memory of course...
            // this is where `IMemory` comes in after all.
            IMemory anotherProcessMemory     = new ExternalMemory(Process.GetCurrentProcess());
            var     physicsFixedOtherProcess = new FixedArrayPtr <AdventurePhysics>((ulong)memoryLocation, itemCount, false, anotherProcessMemory);
            float   averageAirAcceleration2  = physicsFixedOtherProcess.Average(physics => physics.AirAcceleration);

            // What you just witnessed was LINQ over arbitrary structs inside memory of another process.

            // Foreach loop over structs in other processes? Of course.
            float greatestInitialJump = float.MinValue;
            float smallestInitialJump = float.MaxValue;

            foreach (var physics in physicsFixedOtherProcess)
            {
                if (physics.InitialJumpSpeed > greatestInitialJump)
                {
                    greatestInitialJump = physics.InitialJumpSpeed;
                }

                if (physics.InitialJumpSpeed < smallestInitialJump)
                {
                    smallestInitialJump = physics.InitialJumpSpeed;
                }
            }

            Console.WriteLine($"LINQ Over Arbitrary Memory: {averageAirAcceleration} (Average air Acceleration in Sonic Adventure-Heroes)");
            Console.WriteLine($"LINQ Over Memory in Another Process: {greatestInitialJump - smallestInitialJump} (Sonic Adventure-Heroes Physics delta between jump speeds)");
        }
Beispiel #3
0
        /// <summary>
        /// Your own user code starts here.
        /// If this is your first time, do consider reading the notice above.
        /// It contains some very useful information.
        /// </summary>
        public static void Init()
        {
            /*
             *  Reloaded Mod Loader Sample: Memory Manipulation
             *  Architectures supported: X86, X64
             *
             *  An example of memory manipulation in Reloaded, showing how easily it is
             *  possible to write or read structures to and from memory.
             */

            // Want to see this in with a debugger? Uncomment this line.
            // Debugger.Launch();

            /// //////////////////////////////////
            /// Example #1: Reading/Writing Memory
            /// //////////////////////////////////

            // First let's allocate some memory to write our data to.
            // See footnote at 1*, you should really instead use the MemoryBufferManager class for this.
            IntPtr addressOfAllocation = GameProcess.AllocateMemory(2048);

            Bindings.PrintInfo($"Memory allocated at {addressOfAllocation.ToString("X")}");

            // Now let's write some memory to the given address.
            int oneThreeThreeSeven = 1337;

            GameProcess.WriteMemory(addressOfAllocation, ref oneThreeThreeSeven);
            Bindings.PrintInfo($"Written {1337} to address {addressOfAllocation.ToString("X")}");

            // Wait what!? That simple??
            // Well, of course, under the hood we use some generics and fancy C# to automatically convert a type
            // into an array of bytes to write into memory. Feel free to verify the result with Cheat Engine.

            // Let's read this address back.
            int valueAtAddress = GameProcess.ReadMemory <int>(addressOfAllocation);

            Bindings.PrintInfo($"Read {valueAtAddress} from address {addressOfAllocation.ToString("X")}");

            /// //////////////////////////////////////
            /// Example #2: Reading/Writing Structures
            /// //////////////////////////////////////

            // Let's try something a bit more complex now.
            addressOfAllocation += sizeof(int);     // Keep our previously written integer for later so you can verify it's there.
            Bindings.PrintInfo($"Demo #2, Read/Write address now at {addressOfAllocation.ToString("X")}");

            // Let's create and write our own custom structure.
            PlayerCoordinates playerCoordinates = new PlayerCoordinates()
            {
                xPosition = 10,
                yPosition = 1368.62F,
                zPosition = -5324.677F
            };

            // Now let's write it to memory.
            GameProcess.WriteMemory(addressOfAllocation, ref playerCoordinates);
            Bindings.PrintInfo($"Written arbitrary player coordinates {playerCoordinates.xPosition} {playerCoordinates.yPosition} {playerCoordinates.zPosition} to address {addressOfAllocation.ToString("X")}");

            // Wait... Nothing changed?
            // Of course I did say something about generics and fancy C# didn't I?
            // Let's read it back.
            PlayerCoordinates newPlayerCoordinates = GameProcess.ReadMemory <PlayerCoordinates>(addressOfAllocation);

            Bindings.PrintInfo($"Read player coordinates back from {addressOfAllocation.ToString("X")}");

            // Check if we are equal.
            if (newPlayerCoordinates.xPosition == playerCoordinates.xPosition &&
                newPlayerCoordinates.yPosition == playerCoordinates.yPosition &&
                newPlayerCoordinates.zPosition == playerCoordinates.zPosition)
            {
                Bindings.PrintInfo($"Success: See? It's incredibly easy!");
            }
            else
            {
                Bindings.PrintInfo($"Failure: Read back player coordinates are not equal.");
            }

            /// /////////////////////////////////////////
            /// Example #3: Reading/Writing Struct Arrays
            /// /////////////////////////////////////////

            // But what about arrays?
            // Well, libReloaded has an utility for even that.
            // First let's read some arbitrary array from a file and write it to memory.
            Bindings.PrintInfo($"Demo #3, Array Read/Write Test Begin! (This one you should see in a debugger)");

            // First write our arbitrary physics data into memory.
            byte[] physicsData   = File.ReadAllBytes($"{ModDirectory}\\phys.bin"); // ModDirectory is from Reloaded Template
            IntPtr arrayLocation = MemoryBufferManager.Add(physicsData);           // A good example of using MemoryBufferManager (see note below),

            // normally no guarantee our data will fit into our allocated memory,
            // MemoryBufferManager also handles that case without extra code.
            Bindings.PrintInfo($"Character physics data written to {arrayLocation.ToString("X")}");

            // Now let's read back the memory.
            // Length of array for this sample is known as 40.
            FixedArrayPtr <AdventurePhysics> adventurePhysicsArray = new FixedArrayPtr <AdventurePhysics>(arrayLocation, 40);

            // Let's try to read one entry back from memory.
            AdventurePhysics firstEntry = adventurePhysicsArray[0];                     // Wow! It's almost like a native array... isn't it?

            // But we want to know everything! Give me it all!
            AdventurePhysics[] adventurePhysicses = adventurePhysicsArray.ToArray();    // Huh? That's it. Yup.

            // How about writing to one of the entries?
            firstEntry.HangTime      = 1337;
            adventurePhysicsArray[0] = firstEntry;                                      // You've gotta be kidding me...
            Bindings.PrintInfo($"Physics at {arrayLocation.ToString("X")} changed.");
            Bindings.PrintInfo($"Demo end.");
        }
Beispiel #4
0
 /// <summary>
 /// Constructor for the custom enumerator.
 /// </summary>
 /// <param name="parentArrayPtr">Contains original FixedArrayPtr this enumerator was intended for.</param>
 public FixedArrayPtrEnumerator(FixedArrayPtr <TStruct> parentArrayPtr)
 {
     _arrayPtr = parentArrayPtr;
 }